Skip to content

Instantly share code, notes, and snippets.

@Flower7C3
Created August 12, 2025 09:48
Show Gist options
  • Select an option

  • Save Flower7C3/dba997eab4f945851fbfa58c3217c2d3 to your computer and use it in GitHub Desktop.

Select an option

Save Flower7C3/dba997eab4f945851fbfa58c3217c2d3 to your computer and use it in GitHub Desktop.
Wallpaper Crop Script - Automatic creation of wallpapers for vertical layout with aligned centers
#!/usr/bin/env bash
# Wallpaper Crop Script - Automatic creation of wallpapers for vertical layout with aligned centers
# Usage: ./wallpaper-crop.sh <source_image> [--inches external_inches builtin_inches] [--position position]
# Example: ./wallpaper-crop.sh wallpaper.jpg
# Example: ./wallpaper-crop.sh wallpaper.jpg --inches 27 16
# Example: ./wallpaper-crop.sh wallpaper.jpg --inches 27 16 --position center-top
# Function displays help
function show_help() {
echo "Usage: $0 <source_image> [options]"
echo ""
echo "This script creates wallpapers for vertical screens layout with aligned centers."
echo ""
echo "Options:"
echo " --inches | -i <external_inches> <builtin_inches> Physical screen dimensions in inches (default: auto-detect)"
echo " --position | -p <position> Cropping position (default: center-top)"
echo " --help | -h Show this help"
echo ""
echo "Available cropping positions:"
echo " left-top | lt Left top"
echo " center-top | ct Center top"
echo " right-top | rt Right top"
echo " left-middle | lm Left middle"
echo " center-middle | cm Center middle"
echo " right-middle | rm Right middle"
echo " left-bottom | lb Left bottom"
echo " center-bottom | cb Center bottom"
echo " right-bottom | rb Right bottom"
echo ""
echo "Examples:"
echo " $0 wallpaper.jpg"
echo " $0 wallpaper.jpg --inches 27 16"
echo " $0 wallpaper.jpg --inches 27 16 --position left-top"
echo ""
echo "πŸ’‘ If you don't specify physical dimensions, the script will try to detect them automatically."
}
# Function gets screen dimensions from macOS system
function get_screen_dimensions() {
# Get screen information from macOS system
local display_info=$(system_profiler SPDisplaysDataType 2>/dev/null)
if [ -n "$display_info" ]; then
# Extract all resolutions
local all_resolutions=$(echo "$display_info" | grep "Resolution:" | sed 's/.*Resolution: \([0-9]*\) x \([0-9]*\).*/\1 \2/')
local res_array=($all_resolutions)
# Check if we have at least 2 screens (4 values: width and height for each)
if [ ${#res_array[@]} -ge 4 ]; then
# First screen is built-in, second is external
local builtin_width=${res_array[0]}
local builtin_height=${res_array[1]}
local external_width=${res_array[2]}
local external_height=${res_array[3]}
# Return in format: external_width external_height builtin_width builtin_height
echo "$external_width $external_height $builtin_width $builtin_height"
return
fi
fi
# Fallback: try to get resolutions in another way
local displays=$(system_profiler SPDisplaysDataType 2>/dev/null | grep "Resolution:" | sed 's/.*Resolution: \([0-9]*\) x \([0-9]*\).*/\1 \2/')
if [ -z "$displays" ]; then
# Final fallback: use screeninfo command if available
if command -v screeninfo &> /dev/null; then
displays=$(screeninfo | grep -E '[0-9]+x[0-9]+' | head -2 | sed 's/.*\([0-9]*\)x\([0-9]*\).*/\1 \2/')
fi
fi
echo "$displays"
}
# Function automatically detects physical screen dimensions
function get_physical_dimensions() {
local display_info=$(system_profiler SPDisplaysDataType 2>/dev/null)
local external_inches=""
local builtin_inches=""
if [ -n "$display_info" ]; then
# Try to detect external screen (DisplayPort, HDMI, Thunderbolt)
local external_info=$(echo "$display_info" | grep -A 20 -B 5 "DisplayPort\|HDMI\|Thunderbolt" | grep -E "Display Size|Screen Size|Physical Size" | head -1)
if [ -n "$external_info" ]; then
# Extract dimensions from screen information
local external_size=$(echo "$external_info" | grep -oE '[0-9]+(\.[0-9]+)?' | head -1)
if [ -n "$external_size" ]; then
external_inches="$external_size"
echo "πŸ” Detected external screen: ${external_inches}\"" >&2
fi
fi
# Try to detect built-in screen (Built-in)
local builtin_info=$(echo "$display_info" | grep -A 20 -B 5 "Built-in\|Internal" | grep -E "Display Size|Screen Size|Physical Size" | head -1)
if [ -n "$builtin_info" ]; then
local builtin_size=$(echo "$builtin_info" | grep -oE '[0-9]+(\.[0-9]+)?' | head -1)
if [ -n "$builtin_size" ]; then
builtin_inches="$builtin_size"
echo "πŸ” Detected built-in screen: ${builtin_inches}\"" >&2
fi
fi
# If detection failed, try alternative methods
if [ -z "$external_inches" ]; then
# Check if this might be a Retina display (typical dimensions)
local external_res=$(echo "$display_info" | grep "Resolution:" | grep -v "Built-in" | head -1)
if echo "$external_res" | grep -q "1920x1080\|2560x1440\|3840x2160"; then
external_inches="27"
echo "πŸ” Detected external screen (based on resolution): ${external_inches}\"" >&2
fi
fi
if [ -z "$builtin_inches" ]; then
# Check if this might be a Retina display (typical dimensions)
local builtin_res=$(echo "$display_info" | grep "Resolution:" | grep "Built-in" | head -1)
if echo "$builtin_res" | grep -q "2056x1329\|2560x1600\|3024x1964"; then
builtin_inches="16"
echo "πŸ” Detected built-in screen (based on resolution): ${builtin_inches}\"" >&2
fi
fi
fi
# Return dimensions in format: external_inches builtin_inches
echo "$external_inches $builtin_inches"
}
function map_crop_position() {
local position="$1"
case "$position" in
"left-top" | "lt")
echo "left_top"
;;
"center-top" | "ct")
echo "center_top"
;;
"right-top" | "rt")
echo "right_top"
;;
"left-middle" | "lm")
echo "left_middle"
;;
"center-middle" | "cm")
echo "center_middle"
;;
"right-middle" | "rm")
echo "right_middle"
;;
"left-bottom" | "lb")
echo "left_bottom"
;;
"center-bottom" | "cb")
echo "center_bottom"
;;
"right-bottom" | "rb")
echo "right_bottom"
;;
"all")
echo "all"
;;
esac
}
# Function calculates cropping position based on selected position
function calculate_crop_position() {
local position="$1"
local src_width="$2"
local src_height="$3"
local crop_width="$4"
local crop_height="$5"
local x="-1"
local y="-1"
# round up to nearest integer
if [[ "$position" == left_* ]]; then
x=0
fi
if [[ "$position" == center_* ]]; then
x=$(echo "scale=1; ($src_width - $crop_width) / 2 + 0.5" | bc -l | cut -d. -f1)
fi
if [[ "$position" == right_* ]]; then
x=$(echo "scale=1; $src_width - $crop_width + 0.5" | bc -l | cut -d. -f1)
fi
if [[ "$position" == *_top ]]; then
y=0
fi
if [[ "$position" == *_middle ]]; then
y=$(echo "scale=1; ($src_height - $crop_height) / 2 + 0.5" | bc -l | cut -d. -f1)
fi
if [[ "$position" == *_bottom ]]; then
y=$(echo "scale=1; $src_height - $crop_height + 0.5" | bc -l | cut -d. -f1)
fi
echo "$x $y"
}
# Function crops images based on given parameters
function cropper() {
local source_image="$1" # Source image path
local display_name="$2" # Screen name (external/builtin)
local width="$3" # Target width
local height="$4" # Target height
local x_start="$5" # Initial X position
local y_start="$6" # Initial Y position
local position="$7" # Cropping position
# Remove resolution from filename if present
local base_name=$(echo "$source_image" | sed 's/-[0-9]*x[0-9]*\.jpg$//')
# Create output filename
local output_filename="${base_name}-${position}-${display_name}-${width}x${height}.jpg"
printf "🎨 Creating %s [%s] " "$display_name" "$output_filename"
# Crop image using ImageMagick
magick "$source_image" -crop "${width}x${height}+${x_start}+${y_start}" "$output_filename"
# Check if operation succeeded
if [ $? -eq 0 ]; then
# Verify output file was created and has content
if [[ -f "$output_filename" ]] && [[ -s "$output_filename" ]]; then
# Check file size is reasonable (not too small)
local file_size=$(stat -f%z "$output_filename" 2>/dev/null || stat -c%s "$output_filename" 2>/dev/null || echo "0")
if (( file_size < 1000 )); then
echo "⚠️ (file created but very small: ${file_size} bytes)"
else
echo "βœ…"
fi
else
echo "❌ (file not created or empty)"
return 1
fi
else
echo "❌"
return 1
fi
}
# Function to validate command line arguments
validate_arguments() {
local external="$1"
local builtin="$2"
local position="$3"
local file_path="$4"
# Validate external screen dimensions
if ! [[ "$external" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
echo "❌ Error: External screen dimension must be a positive number (e.g. 27 or 27.5)"
return 1
fi
# Check if external screen dimension is reasonable (1-100 inches)
if (( $(echo "$external < 1" | bc -l) )) || (( $(echo "$external > 100" | bc -l) )); then
echo "❌ Error: External screen dimension must be between 1 and 100 inches"
return 1
fi
# Validate built-in screen dimensions
if ! [[ "$builtin" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
echo "❌ Error: Built-in screen dimension must be a positive number (e.g. 16 or 13.3)"
return 1
fi
# Check if built-in screen dimension is reasonable (1-50 inches)
if (( $(echo "$builtin < 1" | bc -l) )) || (( $(echo "$builtin > 50" | bc -l) )); then
echo "❌ Error: Built-in screen dimension must be between 1 and 50 inches"
return 1
fi
# Check if external screen is larger than built-in (reasonable assumption)
if (( $(echo "$external <= $builtin" | bc -l) )); then
echo "⚠️ Warning: External screen ($external\") is not larger than built-in screen ($builtin\")"
echo " This might not be the intended configuration. Continue anyway? (y/N)"
read -r response
if [[ ! "$response" =~ ^[Yy]$ ]]; then
echo "❌ Operation cancelled by user"
return 1
fi
fi
# Validate cropping position
local valid_positions=("left-top" "center-top" "right-top" "left-middle" "center-middle" "right-middle" "left-bottom" "center-bottom" "right-bottom" "all")
local is_valid=false
for valid_pos in "${valid_positions[@]}"; do
if [[ "$position" == "$valid_pos" ]]; then
is_valid=true
break
fi
done
if [[ "$is_valid" == false ]]; then
echo "❌ Error: Invalid cropping position '$position'"
echo " Valid positions: ${valid_positions[*]}"
return 1
fi
# Check if source image was provided
if [[ -z "$file_path" ]]; then
echo "❌ Error: You must provide a source image"
show_help
exit 1
fi
# Check if file exists
if [[ ! -f "$file_path" ]]; then
echo "❌ Error: File '$file_path' does not exist"
return 1
fi
# Check if file is readable
if [[ ! -r "$file_path" ]]; then
echo "❌ Error: File '$file_path' is not readable"
return 1
fi
# Check file size (must be > 0 bytes)
if [[ ! -s "$file_path" ]]; then
echo "❌ Error: File '$file_path' is empty"
return 1
fi
# Check if ImageMagick can identify the file
if ! magick identify -ping -format '%w' "$file_path" >/dev/null 2>&1; then
echo "❌ Error: File '$file_path' is not a valid image format supported by ImageMagick"
echo " Supported formats: JPG, PNG, GIF, BMP, TIFF, etc."
return 1
fi
return 0
}
# Function to validate system requirements
validate_system_requirements() {
# Check if output directory is writable
if [[ ! -w "." ]]; then
echo "❌ Error: Current directory is not writable"
return 1
fi
# Check available disk space (at least 100MB free)
available_space=$(df . | awk 'NR==2 {print $4}')
if (( available_space < 102400 )); then
echo "⚠️ Warning: Low disk space available (${available_space}KB)"
echo " This might cause wallpaper creation to fail"
fi
# Check if ImageMagick is available
if ! command -v magick &> /dev/null; then
echo "❌ Error: ImageMagick (magick) is not installed or not in PATH"
echo " Please install ImageMagick to use this script"
return 1
fi
# Check if bc calculator is available
if ! command -v bc &> /dev/null; then
echo "❌ Error: bc calculator is not installed or not in PATH"
echo " Please install bc to use this script"
return 1
fi
# Check if system_profiler is available (macOS specific)
if ! command -v system_profiler &> /dev/null; then
echo "⚠️ Warning: system_profiler not found, automatic screen detection may fail"
fi
# Check if we're running on macOS
if [[ "$OSTYPE" != "darwin"* ]]; then
echo "⚠️ Warning: This script is designed for macOS"
echo " Some features may not work correctly on other systems"
fi
# Check script permissions
if [[ ! -x "$0" ]]; then
echo "⚠️ Warning: Script is not executable"
echo " Run: chmod +x $0"
fi
# Check if we have enough memory (at least 100MB free)
if command -v vm_stat &> /dev/null; then
memory_info=$(vm_stat | grep "Pages free:" | awk '{print $3}' | sed 's/\.//')
if [[ -n "$memory_info" ]]; then
free_memory_mb=$((memory_info * 4096 / 1024 / 1024))
if (( free_memory_mb < 100 )); then
echo "⚠️ Warning: Low memory available (${free_memory_mb}MB)"
echo " This might cause wallpaper creation to fail"
fi
fi
fi
# Check if we're running as root (not recommended)
if [[ $EUID -eq 0 ]]; then
echo "⚠️ Warning: Running as root is not recommended"
echo " Consider running as a regular user"
fi
return 0
}
echo "=== WALLPAPER CROPPER ==="
echo ""
# Initialize variables
source_image=""
external_inches=""
builtin_inches=""
crop_position="center-top"
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--inches|-i)
if [[ $# -lt 3 ]]; then
echo "❌ Error: --inches requires two arguments"
echo " Usage: --inches <external> <builtin>"
echo " Example: --inches 27 16"
exit 1
fi
external_inches="$2"
builtin_inches="$3"
shift 3
;;
--position|-p)
if [[ $# -lt 2 ]]; then
echo "❌ Error: --position requires one argument"
echo " Usage: --position <position>"
echo " Valid positions: left-top, center-top, right-top, left-middle, center-middle, right-middle, left-bottom, center-bottom, right-bottom, all"
exit 1
fi
crop_position="$2"
shift 2
;;
-h|--help)
show_help
exit 0
;;
-*)
echo "❌ Error: Unknown option $1"
echo "Use --help to show help"
exit 1
;;
*)
if [[ -z "$source_image" ]]; then
# Check if argument looks like an option
if [[ "$1" == -* ]]; then
echo "❌ Error: '$1' looks like an option but is not recognized"
echo " Use --help to see available options"
exit 1
fi
source_image="$1"
else
echo "❌ Error: Too many arguments"
echo " Expected: <source_image>"
echo " Got: $source_image and $1"
exit 1
fi
shift
;;
esac
done
# Validate system requirements
if ! validate_system_requirements; then
exit 1
fi
######### SCREEN DIMENSIONS #########
if [ -n "$external_inches" ] && [ -n "$builtin_inches" ]; then
# User provided dimensions via --inches
echo "πŸ“‹ Using user-provided dimensions!"
else
# Automatic screen detection
echo "πŸ” Automatic screen detection..."
# Detect physical screen dimensions
physical_dimensions=$(get_physical_dimensions)
detected_external=$(echo "$physical_dimensions" | cut -d' ' -f1)
detected_builtin=$(echo "$physical_dimensions" | cut -d' ' -f2)
# Check if dimensions were detected successfully
if [ -n "$detected_external" ] && [ -n "$detected_builtin" ]; then
echo "πŸŽ‰ Physical dimensions detected automatically!"
external_inches="$detected_external"
builtin_inches="$detected_builtin"
else
# Could not detect and user did not provide
echo "❌ Could not automatically detect physical dimensions."
echo "πŸ“ Please provide physical screen dimensions in inches:"
echo -n "πŸ–₯️ External screen: "
read -r external_inches
echo -n "πŸ’» Built-in screen: "
read -r builtin_inches
fi
fi
# Validate all arguments together
if ! validate_arguments "$external_inches" "$builtin_inches" "$crop_position" "$source_image"; then
exit 1
fi
if [[ $crop_position == "all" ]]; then
echo "πŸ”„ Generating wallpapers for all cropping positions..."
$0 --inches $external_inches $builtin_inches --position "left-top" "$source_image"
$0 --inches $external_inches $builtin_inches --position "center-top" "$source_image"
$0 --inches $external_inches $builtin_inches --position "right-top" "$source_image"
$0 --inches $external_inches $builtin_inches --position "left-middle" "$source_image"
$0 --inches $external_inches $builtin_inches --position "center-middle" "$source_image"
$0 --inches $external_inches $builtin_inches --position "right-middle" "$source_image"
$0 --inches $external_inches $builtin_inches --position "left-bottom" "$source_image"
$0 --inches $external_inches $builtin_inches --position "center-bottom" "$source_image"
$0 --inches $external_inches $builtin_inches --position "right-bottom" "$source_image"
echo "βœ… All wallpapers generated successfully!"
exit 0
fi
######### SCREEN DIMENSIONS #########
# Detect screen dimensions from macOS system
screen_dimensions=$(get_screen_dimensions)
# Get screen dimensions from array
external_width=$(echo "$screen_dimensions" | cut -d' ' -f1)
external_height=$(echo "$screen_dimensions" | cut -d' ' -f2)
builtin_width=$(echo "$screen_dimensions" | cut -d' ' -f3)
builtin_height=$(echo "$screen_dimensions" | cut -d' ' -f4)
# Validate screen dimensions
if [[ -z "$external_width" ]] || [[ -z "$external_height" ]] || [[ -z "$builtin_width" ]] || [[ -z "$builtin_height" ]]; then
echo "❌ Error: Failed to detect screen dimensions"
echo " External: ${external_width}x${external_height}"
echo " Built-in: ${builtin_width}x${builtin_height}"
exit 1
fi
# Check if dimensions are reasonable (must be positive and not too large)
if (( external_width <= 0 )) || (( external_height <= 0 )) || (( builtin_width <= 0 )) || (( builtin_height <= 0 )); then
echo "❌ Error: Invalid screen dimensions detected"
echo " External: ${external_width}x${external_height}"
echo " Built-in: ${builtin_width}x${builtin_height}"
exit 1
fi
if (( external_width > 10000 )) || (( external_height > 10000 )) || (( builtin_width > 10000 )) || (( builtin_height > 10000 )); then
echo "❌ Error: Screen dimensions seem unreasonably large"
echo " External: ${external_width}x${external_height}"
echo " Built-in: ${builtin_width}x${builtin_height}"
exit 1
fi
######### SCREEN ASPECT RATIO #########
# Check aspect ratio sanity (should be between 0.5 and 3.0)
external_ratio=$(echo "scale=4; $external_width / $external_height" | bc -l)
builtin_ratio=$(echo "scale=4; $builtin_width / $builtin_height" | bc -l)
if (( $(echo "$external_ratio < 0.5" | bc -l) )) || (( $(echo "$external_ratio > 3.0" | bc -l) )); then
echo "⚠️ Warning: External screen aspect ratio ($external_ratio) seems unusual"
fi
if (( $(echo "$builtin_ratio < 0.5" | bc -l) )) || (( $(echo "$builtin_ratio > 3.0" | bc -l) )); then
echo "⚠️ Warning: Built-in screen aspect ratio ($builtin_ratio) seems unusual"
fi
# Calculate screen diagonals (needed for DPI calculation)
external_diameter=$(( external_width * external_width + external_height * external_height ))
builtin_diameter=$(( builtin_width * builtin_width + builtin_height * builtin_height ))
# Calculate DPI for each screen (diagonal in pixels / diagonal in inches)
external_dpi=$(echo "scale=2; sqrt($external_diameter) / $external_inches" | bc -l 2>/dev/null || echo "0")
builtin_dpi=$(echo "scale=2; sqrt($builtin_diameter) / $builtin_inches" | bc -l 2>/dev/null || echo "0")
# Validate DPI calculations
if [[ "$external_dpi" == "0" ]] || [[ "$builtin_dpi" == "0" ]]; then
echo "❌ Error: Failed to calculate DPI values"
echo " External DPI: $external_dpi"
echo " Built-in DPI: $builtin_dpi"
exit 1
fi
# Check if DPI values are reasonable (typically between 72-300)
if (( $(echo "$external_dpi < 72" | bc -l) )) || (( $(echo "$external_dpi > 300" | bc -l) )); then
echo "⚠️ Warning: External screen DPI ($external_dpi) seems unusual (expected 72-300)"
fi
if (( $(echo "$builtin_dpi < 72" | bc -l) )) || (( $(echo "$builtin_dpi > 300" | bc -l) )); then
echo "⚠️ Warning: Built-in screen DPI ($builtin_dpi) seems unusual (expected 72-300)"
fi
echo "πŸ–₯️ External screen: $external_inches\" ($external_ratio ratio)"
echo "πŸ’» Built-in screen: $builtin_inches\" ($builtin_ratio ratio)"
echo ""
######### ADJUST WALLPAPER SIZE DIMENSIONS #########
external_info="$external_width x $external_height px ($external_dpi dpi)"
builtin_info="$builtin_width x $builtin_height px ($builtin_dpi dpi)"
# Physical scaling logic - adjust dimensions of screen with lower DPI to screen with higher DPI
if (( $(echo "$builtin_dpi < $external_dpi" | bc -l) )); then
# Scale built-in screen up to external screen DPI
echo "πŸ“ˆ Scaling size of built-in screen wallpaper up to external screen DPI"
builtin_width_fixed=$(echo "scale=0; $builtin_width * $external_dpi / $builtin_dpi" | bc -l 2>/dev/null || echo "0")
builtin_height_fixed=$(echo "scale=0; $builtin_height * $external_dpi / $builtin_dpi" | bc -l 2>/dev/null || echo "0")
builtin_dpi_fixed=$(echo "scale=2; sqrt($builtin_width_fixed * $builtin_width_fixed + $builtin_height_fixed * $builtin_height_fixed) / $builtin_inches" | bc -l 2>/dev/null || echo "0")
builtin_ratio_fixed=$(echo "scale=4; $builtin_width_fixed / $builtin_height_fixed" | bc -l)
changes_builtin="$builtin_width_fixed x $builtin_height_fixed px ($builtin_dpi_fixed dpi)"
builtin_width=$builtin_width_fixed
builtin_height=$builtin_height_fixed
builtin_dpi=$builtin_dpi_fixed
else
# Scale external screen up to built-in screen DPI
echo "πŸ“ˆ Scaling size of external screen wallpaper up to built-in screen DPI"
external_width_fixed=$(echo "scale=0; $external_width * $builtin_dpi / $external_dpi" | bc -l 2>/dev/null || echo "0")
external_height_fixed=$(echo "scale=0; $external_height * $builtin_dpi / $external_dpi" | bc -l 2>/dev/null || echo "0")
external_dpi_fixed=$(echo "scale=2; sqrt($external_width_fixed * $external_width_fixed + $external_height_fixed * $external_height_fixed) / $external_inches" | bc -l 2>/dev/null || echo "0")
external_ratio_fixed=$(echo "scale=4; $external_width_fixed / $external_height_fixed" | bc -l)
changes_external=" β†’ $external_width_fixed x $external_height_fixed px ($external_dpi_fixed dpi)"
external_width=$external_width_fixed
external_height=$external_height_fixed
external_dpi=$external_dpi_fixed
fi
echo "πŸ–₯️ External screen wallpaper: $external_info$changes_external"
echo "πŸ’» Built-in screen wallpaper: $builtin_info$changes_builtin"
# Calculate total wallpapers height and max wallpapers width
total_height=$(echo "scale=0; $external_height + $builtin_height" | bc -l)
max_width=$((external_width > builtin_width ? external_width : builtin_width))
echo "πŸ“ Total wallpapers height: $total_height px"
echo "πŸ“ Max wallpapers width: $max_width px"
echo ""
######### SOURCE IMAGE DIMENSIONS #########
# Get source image dimensions
src_width=$(magick identify -ping -format '%w' "$source_image")
src_height=$(magick identify -ping -format '%h' "$source_image")
# Validate source image dimensions
if [[ -z "$src_width" ]] || [[ -z "$src_height" ]]; then
echo "❌ Error: Failed to get source image dimensions"
exit 1
fi
if (( src_width <= 0 )) || (( src_height <= 0 )); then
echo "❌ Error: Invalid source image dimensions: ${src_width}x${src_height}"
exit 1
fi
echo "πŸ–ΌοΈ Source image dimensions: ${src_width} x ${src_height} px"
# Check if image dimensions are reasonable (not too small or too large)
if (( src_width < 100 )) || (( src_height < 100 )); then
echo "⚠️ Warning: Source image dimensions seem very small: ${src_width}x${src_height}"
echo " This might result in poor quality wallpapers"
fi
if (( src_width > 10000 )) || (( src_height > 10000 )); then
echo "⚠️ Warning: Source image dimensions seem very large: ${src_width}x${src_height}"
echo " Processing might take longer than expected"
fi
echo ""
######### SCALE FACTORS #########
# Check if screen dimensions don't exceed source image dimensions
scale_factor_height=1
scale_factor_width=1
# Check height
if (( $(echo "$src_height < $total_height" | bc -l) )); then
echo "⚠️ Warning: Total wallpapers height exceeds source image height"
# Calculate scaling factor (image height / total screen height)
scale_factor_height=$(echo "scale=4; $src_height / $total_height" | bc -l)
echo "πŸ”’ Height scaling factor: $scale_factor_height"
fi
# Check width
if (( $(echo "$src_width < $max_width" | bc -l) )); then
echo "⚠️ Warning: Maximum wallpapers width exceeds source image width"
# Calculate scaling factor (image width / maximum screen width)
scale_factor_width=$(echo "scale=4; $src_width / $max_width" | bc -l)
echo "πŸ”’ Width scaling factor: $scale_factor_width"
fi
# Apply scaling only if needed
if (( $(echo "$scale_factor_height < 1" | bc -l) || $(echo "$scale_factor_width < 1" | bc -l) )); then
# Validate scaling factors
if (( $(echo "$scale_factor_height <= 0" | bc -l) )) || (( $(echo "$scale_factor_width <= 0" | bc -l) )); then
echo "❌ Error: Invalid scaling factors calculated"
echo " Height factor: $scale_factor_height"
echo " Width factor: $scale_factor_width"
exit 1
fi
# Check if scaling factors are reasonable (not too small)
if (( $(echo "$scale_factor_height < 0.1" | bc -l) )) || (( $(echo "$scale_factor_width < 0.1" | bc -l) )); then
echo "⚠️ Warning: Scaling factors are very small, this might result in poor quality"
echo " Height factor: $scale_factor_height"
echo " Width factor: $scale_factor_width"
fi
if (( $(echo "$scale_factor_height < $scale_factor_width" | bc -l) )); then
scale_factor=$scale_factor_height
echo "πŸ“ Using height scaling factor (more restrictive): $scale_factor"
else
scale_factor=$scale_factor_width
echo "πŸ“ Using width scaling factor (more restrictive): $scale_factor"
fi
# Scale screen dimensions proportionally
external_width_scaled=$(echo "scale=0; $external_width * $scale_factor / 1" | bc -l)
external_height_scaled=$(echo "scale=0; $external_height * $scale_factor / 1" | bc -l)
builtin_width_scaled=$(echo "scale=0; $builtin_width * $scale_factor / 1" | bc -l)
builtin_height_scaled=$(echo "scale=0; $builtin_height * $scale_factor / 1" | bc -l)
# Update screen dimensions
external_width=$external_width_scaled
external_height=$external_height_scaled
builtin_width=$builtin_width_scaled
builtin_height=$builtin_height_scaled
echo ""
fi
######### CROPPING POSITION #########
crop_position="$(map_crop_position "$crop_position")"
echo "πŸ“ Cropping position: ${crop_position/_/ }"
# Calculate cropping position for external screen
external_pos=$(calculate_crop_position "$crop_position" "$src_width" "$src_height" "$external_width" "$(echo "scale=0; $external_height + $builtin_height" | bc -l)")
external_x_start=$(echo "$external_pos" | cut -d' ' -f1)
external_y_start=$(echo "$external_pos" | cut -d' ' -f2)
# Calculate cropping position for built-in screen
builtin_x_start=$(echo "scale=1; $external_x_start + $external_width/2 - $builtin_width/2" | bc -l | cut -d. -f1)
builtin_y_start=$(echo "scale=1; $external_y_start + $external_height" | bc -l | cut -d. -f1)
# Validate cropping coordinates
if [[ -z "$external_x_start" ]] || [[ -z "$external_y_start" ]] || [[ -z "$builtin_x_start" ]] || [[ -z "$builtin_y_start" ]]; then
echo "❌ Error: Failed to calculate cropping coordinates"
echo " External: x=$external_x_start, y=$external_y_start"
echo " Built-in: x=$builtin_x_start, y=$builtin_y_start"
exit 1
fi
# Check if coordinates are valid numbers
if ! [[ "$external_x_start" =~ ^-?[0-9]+$ ]] || ! [[ "$external_y_start" =~ ^-?[0-9]+$ ]] || ! [[ "$builtin_x_start" =~ ^-?[0-9]+$ ]] || ! [[ "$builtin_y_start" =~ ^-?[0-9]+$ ]]; then
echo "❌ Error: Invalid cropping coordinates (not integers)"
echo " External: x=$external_x_start, y=$external_y_start"
echo " Built-in: x=$builtin_x_start, y=$builtin_y_start"
exit 1
fi
# Check if coordinates are within image bounds
if (( external_x_start < 0 )) || (( external_y_start < 0 )) || (( builtin_x_start < 0 )) || (( builtin_y_start < 0 )); then
echo "❌ Error: Cropping coordinates cannot be negative"
echo " External: x=$external_x_start, y=$external_y_start"
echo " Built-in: x=$builtin_x_start, y=$builtin_y_start"
exit 1
fi
if (( external_x_start + external_width > src_width )) || (( external_y_start + external_height > src_height )); then
echo "❌ Error: External screen crop area exceeds image boundaries"
echo " Crop area: ${external_width}x${external_height} at ($external_x_start, $external_y_start)"
echo " Image size: ${src_width}x${src_height}"
exit 1
fi
if (( builtin_x_start + builtin_width > src_width )) || (( builtin_y_start + builtin_height > src_height )); then
echo "❌ Error: Built-in screen crop area exceeds image boundaries"
echo " Crop area: ${builtin_width}x${builtin_height} at ($builtin_x_start, $builtin_y_start)"
echo " Image size: ${src_width}x${src_height}"
exit 1
fi
# Final validation before creating wallpapers
if (( external_width <= 0 )) || (( external_height <= 0 )) || (( builtin_width <= 0 )) || (( builtin_height <= 0 )); then
echo "❌ Error: Invalid final dimensions for cropping"
echo " External: ${external_width}x${external_height}"
echo " Built-in: ${builtin_width}x${builtin_height}"
exit 1
fi
echo "πŸ–₯️ External screen wallpaper cropped to: ${src_width}x${src_height}+${external_x_start}+${external_y_start} β†’ ${external_width}x${external_height}"
echo "πŸ’» Built-in screen wallpaper cropped to: ${src_width}x${src_height}+${builtin_x_start}+${builtin_y_start} β†’ ${builtin_width}x${builtin_height}"
echo ""
######### CREATE WALLPAPERS #########
echo "🎨 Creating wallpapers..."
if ! cropper "$source_image" "1_external" "$external_width" "$external_height" "$external_x_start" "$external_y_start" "$crop_position"; then
echo "❌ Error: Failed to create external screen wallpaper"
exit 1
fi
if ! cropper "$source_image" "2_builtin" "$builtin_width" "$builtin_height" "$builtin_x_start" "$builtin_y_start" "$crop_position"; then
echo "❌ Error: Failed to create built-in screen wallpaper"
exit 1
fi
echo ""
echo "🎯 Done! Created wallpapers for $external_inches\" external screen and $builtin_inches\" built-in screen in vertical layout with '${crop_position/_/ }' as cropping position."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment