#!/usr/bin/env bash # __ __ __ # .----.--| | .-----.----.----.|__|.-----.| |_ # | __| _ | |__ --| __| _|| || _ || _| # |____|_____| |_____|____|__| |__|| __||____| # |__| # # script to make cd jewel case inserts easily # by sun https://sx7n8.tech/ # # dependencies are: imagemagick, bash, awk # TODO: # - !!! Add support for back insert !!! # - Remove bugs # - Add more paper types # - Make DPI a command line option # - Add different folding points for inserts # - Clean up code and add more comments # - Improve input and output further # usage message USAGE="Usage: $0 -p -c -b [-i ] [-m ] -o " # help message HELP="Script to create printable CD jewel case inserts Usage: $0 -p -c -b [-i ] [-m ] -o Required options: -p Paper format a4 | letter -c Album cover path Path to cover image -b Back type no | image -o Output file Path to save the resulting insert (NO PNG) Optional options: -i Back image path Required if back type is 'image' -m Border width (px) Adds a border around the cover/back DO NOT USE PNG FOR OUTPUT " # error function error() { echo -e "Error: $1" >&2 echo -e "$USAGE" >&2 exit 1 } # file existance check check_file_exists() { if [ ! -f "$1" ]; then error "File '$1' does not exist." fi } # file existance check but opposite check_output_file() { if [ -f "$1" ]; then error "Output file '$1' already exists." fi } # getops argument handling while getopts "hp:c:b:i:m:o:" o; do case "${o}" in h) echo -e "$HELP" exit ;; p) if [[ "$OPTARG" != "a4" && "$OPTARG" != "letter" ]]; then error "Invalid paper type '$OPTARG'. Must be 'a4' or 'letter'." fi PAPER="$OPTARG" ;; c) check_file_exists "$OPTARG" COVER="$OPTARG" COVERSIZE="$(identify -format "%w" "$COVER")" ;; b) if [[ "$OPTARG" != "no" && "$OPTARG" != "image" ]]; then error "Invalid back type '$OPTARG'. Must be 'no' or 'image'." fi BACKTYPE="$OPTARG" ;; i) if [[ "$BACKTYPE" != "image" ]]; then error "-i option requires back type to be 'image'." fi check_file_exists "$OPTARG" BACKIMG="$OPTARG" ;; m) BORDER="TRUE" BORDER_WIDTH="$OPTARG" ;; o) check_output_file "$OPTARG" OUTPUT="$OPTARG" ;; *) echo -e "$USAGE" exit 1 ;; esac done # check if something is missing [[ -z "$PAPER" ]] && error "Missing paper format (-p)." [[ -z "$COVER" ]] && error "Missing cover image (-c)." [[ -z "$BACKTYPE" ]] && error "Missing back type (-b)." [[ -z "$OUTPUT" ]] && error "Missing output file (-o)." [[ "$BACKTYPE" == "image" && -z "$BACKIMG" ]] && error "Missing back image (-i) for back type 'image'." # function to convert mm to px with dpi CONVERT() { awk -v mm="$1" -v dpi="$2" 'BEGIN{printf("%d", mm/25.4*dpi + 0.5)}'; } # DPI of paper DPI="300" # cover art size (mm) CO_MM="120" CO_PX="$(CONVERT "$CO_MM" "$DPI")" # Width and Height of paper in mm A4MM_W="210" A4MM_H="297" LTMM_W="216" LTMM_H="279" # same values in pixels A4PX="$(CONVERT "$A4MM_W" "$DPI")x$(CONVERT "$A4MM_H" "$DPI")" LTPX="$(CONVERT "$LTMM_W" "$DPI")x$(CONVERT "$LTMM_H" "$DPI")" # assign to the 'size' variable the right value if [ "$PAPER" = "a4" ]; then SIZE=$A4PX elif [ "$PAPER" = "letter" ]; then SIZE=$LTPX else echo "what the fuck did you do" exit fi # create a blank file with the specified paper type magick -colorspace sRGB -type TrueColor -depth 8 -size $SIZE canvas:white "$OUTPUT" > /dev/null # draws border (rectangle) if [ "$BORDER" = "TRUE" ]; then INSET=$((BORDER_WIDTH / 2)) magick ""$OUTPUT"" \( -size $((CO_PX + 2 * BORDER_WIDTH))x$((CO_PX * 2 + 2 * BORDER_WIDTH)) xc:none -colorspace sRGB -type TrueColor -depth 8 -fill none -stroke black -strokewidth $BORDER_WIDTH -draw "rectangle $INSET,$INSET $((CO_PX + BORDER_WIDTH - 1)),$((CO_PX * 2 + BORDER_WIDTH - 1))" \) -gravity center -composite ""$OUTPUT"" fi # add the cover art set to the right size, rotated left by 90d and shifted up by (cover art size) / 2 magick -colorspace sRGB -type TrueColor -depth 8 "$OUTPUT" \( "$COVER" -resize ${CO_PX}x${CO_PX} -rotate 270 \) -gravity center -geometry +0-$((CO_PX/2)) -composite "$OUTPUT" > /dev/null # adds back if [ "$BACKTYPE" = "image" ]; then magick -colorspace sRGB -type TrueColor -depth 8 "$OUTPUT" \( "$BACKIMG" -resize ${CO_PX}x${CO_PX} -rotate 270 \) -gravity center -geometry +0+$((CO_PX/2)) -composite "$OUTPUT" > /dev/null else magick -colorspace sRGB -type TrueColor -depth 8 "$OUTPUT" \( -size ${CO_PX}x${CO_PX} xc:'#FFFFFF' \) -gravity center -geometry +0+$((CO_PX/2)) -composite "$OUTPUT" > /dev/null fi