Skip to content

Instantly share code, notes, and snippets.

@nkrebs13
Created January 22, 2026 02:22
Show Gist options
  • Select an option

  • Save nkrebs13/a410a025603d1d950a196613ccee9032 to your computer and use it in GitHub Desktop.

Select an option

Save nkrebs13/a410a025603d1d950a196613ccee9032 to your computer and use it in GitHub Desktop.
ADB Screenshot Comparison Tool
#!/bin/bash
# ADB Screenshot Comparison Tool
# Dependencies: adb, imagemagick
# Usage: adb-compare
set -e
# ============================================================================
# Configuration
# ============================================================================
OUTPUT_DIR="$HOME/Downloads"
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
TEMP_DIR=$(mktemp -d)
GAP_WIDTH=12
LABEL_FONT="Helvetica-Bold"
LABEL_SIZE=96
LABEL_COLOR="#ff00ff"
LABEL_OFFSET=28
GRID_COLOR="red"
GRID_STROKE=3
GRID_DASH=10
# ============================================================================
# Cleanup
# ============================================================================
cleanup() {
rm -rf "$TEMP_DIR"
}
trap cleanup EXIT
# ============================================================================
# Dependency Check
# ============================================================================
check_dependencies() {
local missing=()
if ! command -v adb &> /dev/null; then
missing+=("adb")
fi
if ! command -v magick &> /dev/null; then
missing+=("imagemagick (magick command)")
fi
if [ ${#missing[@]} -gt 0 ]; then
echo "Error: Missing required dependencies:"
for dep in "${missing[@]}"; do
echo " - $dep"
done
echo ""
echo "Install with:"
echo " brew install android-platform-tools # for adb"
echo " brew install imagemagick # for magick"
exit 1
fi
}
# ============================================================================
# Device Selection
# ============================================================================
get_device() {
local devices
devices=$(adb devices | grep -v "^List" | grep -v "^$" | awk '{print $1}')
if [ -z "$devices" ]; then
echo "Error: No Android devices found."
echo ""
echo "Troubleshooting:"
echo " 1. Ensure USB debugging is enabled on your device"
echo " 2. Check the USB connection"
echo " 3. Run 'adb devices' to verify connection"
echo " 4. Accept the USB debugging prompt on your device"
exit 1
fi
local device_count
device_count=$(echo "$devices" | wc -l | tr -d ' ')
if [ "$device_count" -eq 1 ]; then
DEVICE=$(echo "$devices" | head -1)
echo "Using device: $DEVICE"
else
echo "Multiple devices found:"
local i=1
local device_array=()
while IFS= read -r device; do
device_array+=("$device")
echo " $i) $device"
((i++))
done <<< "$devices"
echo ""
read -rp "Select device [1-$device_count]: " choice
if ! [[ "$choice" =~ ^[0-9]+$ ]] || [ "$choice" -lt 1 ] || [ "$choice" -gt "$device_count" ]; then
echo "Error: Invalid selection"
exit 1
fi
DEVICE="${device_array[$((choice-1))]}"
echo "Using device: $DEVICE"
fi
}
# ============================================================================
# Screenshot Capture
# ============================================================================
capture_screenshot() {
local output_file="$1"
local screenshot_num="$2"
echo ""
read -rp "Press Enter to capture screenshot $screenshot_num..."
echo "Capturing..."
adb -s "$DEVICE" exec-out screencap -p > "$output_file"
if [ ! -s "$output_file" ]; then
echo "Error: Failed to capture screenshot"
exit 1
fi
echo "Screenshot $screenshot_num captured."
}
# ============================================================================
# Image Processing
# ============================================================================
add_label() {
local input="$1"
local output="$2"
local label="$3"
local dimensions
dimensions=$(magick identify -format "%wx%h" "$input")
local height=${dimensions#*x}
magick "$input" \
-font "$LABEL_FONT" \
-pointsize "$LABEL_SIZE" \
-fill "$LABEL_COLOR" \
-gravity South \
-annotate +0+"$LABEL_OFFSET" "$label" \
"$output"
}
create_grid_overlay() {
local input="$1"
local output="$2"
local dimensions
dimensions=$(magick identify -format "%wx%h" "$input")
local width=${dimensions%x*}
local height=${dimensions#*x}
# Calculate grid positions
# 3 vertical lines (4 columns)
local v1=$((width / 4))
local v2=$((width / 2))
local v3=$((width * 3 / 4))
# 7 horizontal lines (8 rows)
local h1=$((height / 8))
local h2=$((height * 2 / 8))
local h3=$((height * 3 / 8))
local h4=$((height * 4 / 8))
local h5=$((height * 5 / 8))
local h6=$((height * 6 / 8))
local h7=$((height * 7 / 8))
# Build draw commands with MVG dash array syntax
local draw_cmds=""
draw_cmds+="stroke-dasharray $GRID_DASH $GRID_DASH "
draw_cmds+="line $v1,0 $v1,$height "
draw_cmds+="line $v2,0 $v2,$height "
draw_cmds+="line $v3,0 $v3,$height "
draw_cmds+="line 0,$h1 $width,$h1 "
draw_cmds+="line 0,$h2 $width,$h2 "
draw_cmds+="line 0,$h3 $width,$h3 "
draw_cmds+="line 0,$h4 $width,$h4 "
draw_cmds+="line 0,$h5 $width,$h5 "
draw_cmds+="line 0,$h6 $width,$h6 "
draw_cmds+="line 0,$h7 $width,$h7 "
magick "$input" \
-stroke "$GRID_COLOR" \
-strokewidth "$GRID_STROKE" \
-draw "$draw_cmds" \
"$output"
}
stitch_images() {
local img1="$1"
local img2="$2"
local output="$3"
# Create transparent gap
local dimensions
dimensions=$(magick identify -format "%h" "$img1")
local height=$dimensions
magick -size "${GAP_WIDTH}x${height}" xc:transparent "$TEMP_DIR/gap.png"
# Stitch side by side
magick "$img1" "$TEMP_DIR/gap.png" "$img2" +append "$output"
}
# ============================================================================
# Main
# ============================================================================
main() {
echo "=== ADB Screenshot Comparison Tool ==="
echo ""
# Check dependencies
check_dependencies
# Get device
get_device
# Configuration prompts
echo ""
read -rp "Label for image 1 (or press Enter for none): " label1
read -rp "Label for image 2 (or press Enter for none): " label2
# Capture screenshots
local raw1="$TEMP_DIR/raw1.png"
local raw2="$TEMP_DIR/raw2.png"
capture_screenshot "$raw1" "1"
capture_screenshot "$raw2" "2"
# Check dimensions
local dim1 dim2
dim1=$(magick identify -format "%wx%h" "$raw1")
dim2=$(magick identify -format "%wx%h" "$raw2")
if [ "$dim1" != "$dim2" ]; then
echo ""
echo "Warning: Image dimensions differ ($dim1 vs $dim2)"
echo "Continuing anyway..."
fi
# Process images
echo ""
echo "Processing images..."
local proc1="$TEMP_DIR/proc1.png"
local proc2="$TEMP_DIR/proc2.png"
cp "$raw1" "$proc1"
cp "$raw2" "$proc2"
# Add labels if non-empty (trimmed)
label1_trimmed=$(echo "$label1" | xargs)
label2_trimmed=$(echo "$label2" | xargs)
if [ -n "$label1_trimmed" ]; then
add_label "$proc1" "$TEMP_DIR/labeled1.png" "$label1_trimmed"
proc1="$TEMP_DIR/labeled1.png"
fi
if [ -n "$label2_trimmed" ]; then
add_label "$proc2" "$TEMP_DIR/labeled2.png" "$label2_trimmed"
proc2="$TEMP_DIR/labeled2.png"
fi
# Generate outputs
local output_base="$OUTPUT_DIR/comparison_$TIMESTAMP"
local output_plain="${output_base}.png"
local output_grid="${output_base}_grid.png"
echo "Generating comparison images..."
# Plain comparison
stitch_images "$proc1" "$proc2" "$output_plain"
# Grid comparison
local grid1="$TEMP_DIR/grid1.png"
local grid2="$TEMP_DIR/grid2.png"
create_grid_overlay "$proc1" "$grid1"
create_grid_overlay "$proc2" "$grid2"
stitch_images "$grid1" "$grid2" "$output_grid"
echo ""
echo "Created:"
echo " $output_plain"
echo " $output_grid"
# Keep originals prompt
echo ""
read -rp "Keep original screenshots? [y/N]: " keep_originals
if [[ "$keep_originals" =~ ^[Yy]$ ]]; then
cp "$raw1" "${output_base}_1.png"
cp "$raw2" "${output_base}_2.png"
echo "Saved:"
echo " ${output_base}_1.png"
echo " ${output_base}_2.png"
fi
# Open results
echo ""
echo "Opening comparison images..."
open "$output_plain"
open "$output_grid"
echo ""
echo "Done!"
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment