From 92f22b94319f622a6c00722354dfbe6c38ead2b1 Mon Sep 17 00:00:00 2001 From: Tilman Kranz Date: Sun, 10 Dec 2023 13:34:18 +0100 Subject: [PATCH 1/7] keep mean colors in detected components --- 02-convert.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/02-convert.sh b/02-convert.sh index 9b6c4c4..a4506ed 100755 --- a/02-convert.sh +++ b/02-convert.sh @@ -95,6 +95,7 @@ else -define connected-components:verbose=true \ -define connected-components:exclude-header=true \ -define connected-components:sort-order=increasing \ + -define connected-components:mean-color=true \ -define connected-components:area-threshold="$area_treshold" \ -virtual-pixel None \ -connected-components "$connected_components" \ From 46441d9e976447af0770892a9be76c97d4482e14 Mon Sep 17 00:00:00 2001 From: Tilman Kranz Date: Sun, 10 Dec 2023 13:35:04 +0100 Subject: [PATCH 2/7] combine all scripts to single worker script --- 01-rename.sh | 41 ------ 02-convert.sh | 193 ---------------------------- 03-pdf.sh | 98 -------------- run.sh | 345 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 345 insertions(+), 332 deletions(-) delete mode 100755 01-rename.sh delete mode 100755 02-convert.sh delete mode 100755 03-pdf.sh create mode 100755 run.sh diff --git a/01-rename.sh b/01-rename.sh deleted file mode 100755 index 625db2a..0000000 --- a/01-rename.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -## -# Main Program - -dir=$(dirname "$(readlink -f "$0")") -origdir="$dir/orig" -indir="$dir/in" - -if ! cd "$dir" ; then - echo "ERROR: Could not change to directory \"$dir\"; aborted." >&2 - exit 1 -elif ! test -d "$origdir" ; then - echo "ERROR: Directory \"$origdir\" not found; aborted." >&2 - exit 1 -elif ! mkdir -p "$indir" ; then - echo "ERROR: Could not create directory \"$indir\"; aborted." >&2 - exit 1 -elif ! rm -f -- "$indir/"*.jpg ; then - echo "ERROR: Could not remove files in \"$indir\"; aborted." >&2 - exit 1 -else - i=1 - rv=0 - - while read -r jpg ; do - renamed=$(printf "%02d" "$i").jpg - - if cp "$jpg" "$indir/$renamed" ; then - echo "INFO: Copied \"$jpg\" to \"$renamed\"." >&2 - else - echo "WARNING: Could not copy \"$jpg\" to \"$renamed\"." >&2 - rv=1 - fi - - i=$((i+1)) - done < <(ls --reverse --sort time -- "$origdir/"*.jpg) - - exit "$rv" -fi - diff --git a/02-convert.sh b/02-convert.sh deleted file mode 100755 index a4506ed..0000000 --- a/02-convert.sh +++ /dev/null @@ -1,193 +0,0 @@ -#!/bin/bash - -## -# Configuration - -# Before morphology analysis, reduce image dimensions by this factor -simplify=2 - -# Morphology to apply to reduce content to main area -morphology="Open:6" -morphology_shape="Disk" - -# Number of colors images are quantized to for component detection -colors=4 - -# Neighbors to evaluate when detecting connected components -connected_components=8 - -# Area treshold for connected components detection -area_treshold=1000 - -# Sigmoidal contrast adjustment used when trimming -sigmoidal_contrast_trim="30,30%" - -# Sigmoidal contrast adjustment visible in result images -sigmoidal_contrast="45,50%" - -# Number of colors result images are quantized to -posterize=6 - -# Keep intermediate images after processing (note that they will be removed in -# any case at the next run of this script) -keep_tmpfiles=true - -## -# Main Program - -dir="$(dirname "$(readlink -f "$0")")" -tmpdir="$dir/tmp" -indir="$dir/in" -comdir="$dir/com" -outdir="$dir/out" -resize_percent=$((100/simplify)) - -if ! cd "$dir" ; then - echo "ERROR: Could not change to directory \"$dir\"; aborted." >&2 - exit 1 -elif ! mkdir -p "$comdir" "$outdir" "$tmpdir" ; then - echo "ERROR: Could not create working directories; aborted." >&2 - exit 1 -elif ! rm -f -- "$comdir/"*.* ; then - echo "ERROR: Could not delete existing component files; aborted." >&2 - exit 1 -elif ! rm -f -- "$tmpdir/"*.* ; then - echo "ERROR: Could not delete existing tempfiles; aborted." >&2 - exit 1 -elif ! rm -f -- "$outdir/"*.* ; then - echo "ERROR: Could not delete existing results; aborted." >&2 - exit 1 -else - rv=0 - - for jpg in "$indir/"*.jpg ; do - base=$(basename "$jpg" .jpg) - tmp1="$tmpdir/$base.tmp1.png" - tmp2="$tmpdir/$base.tmp2.png" - com="$tmpdir/$base.com.png" - trimmed="$tmpdir/$base.trimmed.png" - inf="$tmpdir/$base.txt" - out="$outdir/$base.png" - - if ! convert \ - "$jpg" \ - -colorspace RGB \ - -sigmoidal-contrast "$sigmoidal_contrast_trim" \ - -resize "$resize_percent%" \ - -colors "$colors" \ - -morphology "$morphology" "$morphology_shape" \ - "$tmp1" - then - echo "ERROR: Could not create test image \"$tmp1\"; skipped." >&2 - rv=1 - continue - fi - - draw=() - v=255 - - while read -r primitive ; do - draw+=("-fill" "rgb($v,$v,$v)" "-draw" "$primitive") - v=$((v-2)) - done < <( - convert \ - "$tmp1" \ - -define connected-components:verbose=true \ - -define connected-components:exclude-header=true \ - -define connected-components:sort-order=increasing \ - -define connected-components:mean-color=true \ - -define connected-components:area-threshold="$area_treshold" \ - -virtual-pixel None \ - -connected-components "$connected_components" \ - -auto-level \ - "$com" | \ - perl -e ' - while(<>){ - chomp; - next unless /(\d+)x(\d+)\+(\d+)\+(\d+)/; - printf - STDERR - "DEBUG: component: $_\n"; - printf - "rectangle %d,%d,%d,%d\n", - $1, $2, $1+$3, $2+$4; - } - - ' | \ - sort | \ - uniq - ) - - printf "DEBUG: connected components in \"%s\":" "$tmp1" - for d in "${draw[@]}" ; do - printf " \"%s\"" "$d" - done - printf "\n" - - if ! convert \ - "$tmp1" \ - -fill black -colorize 100 \ - "${draw[@]}" \ - "$tmp2" - then - echo "ERROR: Could not convert \"$tmp1\" to \"$tmp2\"; skipped." >&2 - rv=1 - continue - elif ! convert \ - "$tmp2" \ - -trim info: \ - > "$inf" - then - echo "ERROR: Could not determine trim info from \"$tmp2\"; skipped." >&2 - rv=1 - continue - fi - - if "$keep_tmpfiles" ; then - if ! convert \ - "$tmp2" \ - -trim \ - "$trimmed" - then - echo "ERROR: Could not test trim \"$tmp2\"; skipped." >&2 - rv=1 - continue - fi - fi - - # upscale crop area from smaller temporary picture sizes - crop=$(simplify=$simplify perl -MEnv -e ' - while(<>) { - chomp(); - s/(\d+)/$1*${simplify}/eg; - /(\d+)x(\d+) \d+x\d+\+(\d+)\+(\d+)/ && do { - print $1."x".$2."+".$3."+".$4; - } - } - ' < "$inf") - - if ! "$keep_tmpfiles" ; then - if ! rm -f -- "$tmp1" "$tmp2" "$trimmed" "$inf" ; then - echo "WARNING: Could not remove temporary files in \"$dir/tmp\"." >&2 - rv=1 - fi - fi - - echo "Processing $base: crop=$crop ..." - - if ! convert \ - "$jpg" \ - -crop "$crop" \ - -sigmoidal-contrast "$sigmoidal_contrast" \ - +dither -posterize "$posterize" \ - "$out" - then - echo "ERROR: Could not process \"$jpg\"; skipped." >&2 - rv=1 - continue - fi - done - - exit "$rv" -fi - diff --git a/03-pdf.sh b/03-pdf.sh deleted file mode 100755 index 057a37f..0000000 --- a/03-pdf.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash -# shellcheck disable=SC2046 - -## -# Configuration - -# Paper size of all pages -paper="a4paper" - -# Offset in page where image should be placed -offset="1cm 3cm" - -# Factor to scale image by before placing in page -scale=0.75 - -# Filename of complete result PDF -result="pdf/result.pdf" - -## -# Main Program - -dir="$(dirname "$(readlink -f "$0")")" - -if ! cd "$dir" ; then - echo "ERROR: Could not change to directory \"$dir\"; aborted." >&2 - exit 1 -elif ! mkdir -p pdf tmp ; then - echo "ERROR: Could not create \"$dir/{pdf,tmp}\"; aborted." >&2 - exit 1 -elif ! rm -f -- "pdf/"*.* ; then - echo "ERROR: Could not delete existing results in \"$dir/pdf\"; aborted." >&2 - exit 1 -else - rv=0 - - for png in "out/"*.png ; do - echo "INFO: Processing \"$png\" ..." >&2 - - read -r width height < <( - identify -verbose "$png" | \ - perl -ne '/Geometry: (\d+)x(\d+)/ && print "$1 $2"' - ) - - if [[ -z $width ]] || [[ -z $height ]] ; then - echo "ERROR: Could not identify width or height of \"$png\"; skipped." >&2 - rv=1 - continue - elif [[ $width -gt $height ]] ; then - backdrop=template/a4paper/landscape.pdf - jam_landscape=--landscape - else - backdrop=template/a4paper/portrait.pdf - jam_landscape=--no-landscape - fi - - base=$(basename "$png" .png) - pdf=tmp/$base.pdf - jammed=tmp/$base-pdfjam.pdf - backdropped=tmp/$base.backdropped.pdf - - if ! convert "$png" "$pdf" ; then - echo "ERROR: Could not convert \"$png\" to PDF; skipped." >&2 - rv=1 - continue - elif ! pdfjam \ - --quiet \ - --outfile tmp \ - --paper "$paper" \ - "$jam_landscape" \ - --scale "$scale" \ - --offset "$offset" \ - "$pdf" - then - echo "ERROR: Could not align \"$pdf\"; skipped." >&2 - rv=1 - continue - elif ! pdftk \ - "$jammed" \ - stamp "$backdrop" \ - output "$backdropped" - then - echo "ERROR: Could not watermark \"$pdf\"; skipped." >&2 - rv=1 - continue - fi - done - - if ! pdftk $(ls -- "tmp/"*.backdropped.pdf) cat output "$result" ; then - echo "ERROR: Could not concatenate \"$result\"." >&2 - rv=1 - elif ! rm -f -- "tmp/"*.pdf ; then - echo "ERROR: Could not remove tempfiles in \"$dir/tmp\"." >&2 - rv=1 - fi - - exit "$rv" -fi - diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..4f1a6ea --- /dev/null +++ b/run.sh @@ -0,0 +1,345 @@ +#!/bin/bash + +## +# Configuration + +# Before morphology analysis, reduce image dimensions by this factor +simplify=2 + +# Morphology to apply to reduce content to main area +morphology="Open:6" +morphology_shape="Disk" + +# Number of colors images are quantized to for component detection +colors=4 + +# Neighbors to evaluate when detecting connected components +connected_components=8 + +# Area treshold for connected components detection +area_treshold=1000 + +# Sigmoidal contrast adjustment used when trimming +sigmoidal_contrast_trim="30,30%" + +# Sigmoidal contrast adjustment visible in result images +sigmoidal_contrast="45,50%" + +# Number of colors result images are quantized to +posterize=6 + +# Keep intermediate images after processing (note that they will be removed in +# any case at the next run of this script) +keep_tmpfiles=true + +# Paper size of all pages +paper="a4paper" + +# Offset in page where image should be placed +offset="1cm 3cm" + +# Factor to scale image by before placing in page +scale=0.75 + +# Filename of complete result PDF +result="pdf/result.pdf" + +## +# Functions + +log() { + level=$1 + msg=$2 + + printf "%s: %s\n" "$level" "$msg" >&2 +} + +error() { + log ERROR "$1" + + exit "${2:-1}" +} + +warning() { + log WARNING "$1" +} + +info() { + log INFO "$1" +} + +## +# Arguments + +dir=$1 + +if [[ -z $dir ]] ; then + error "Usage: $0 DIR" +fi + +origdir=$(dirname "$(readlink -f "$dir")") + +if [[ ! -d $origdir ]] ; then + error "Directory not found: $dir ($origdir)" +fi + +## +# Main Program + +job_id=$(printf "%s" "$origdir" | sha256sum | cut -d" " -f1) + +if [[ -n $TMP ]] ; then + tmp_base=$TMP/photos2pdf/$job_id +elif [[ -n $XDG_RUNTIME_DIR ]] ; then + tmp_base=$XDG_RUNTIME_DIR/photos2pdf/$job_id +else + tmp_base=/tmp/photos2pdf/$job_id +fi + +if ! mkdir -p "$tmp_base" ; then + error "Could not create temporary workign directory $tmp_base; aborted" +fi + +indir="$tmp_base/in" +tmpdir="$tmp_base/tmp" +outdir="$tmp_base/out" +pdfdir="$tmp_base/pdf" + +if ! test -d "$origdir" ; then + error "Directory \"$origdir\" not found; aborted." +elif ! mkdir -p "$indir" "$outdir" "$pdfdir" "$tmpdir" ; then + error "Could not create working directories; aborted." +elif ! rm -f -- "$indir/"*.* ; then + error "Could not delete existing input files; aborted." +elif ! rm -f -- "$tmpdir/"*.* ; then + error "Could not delete existing tempfiles; aborted." +elif ! rm -f -- "$outdir/"*.* ; then + error "Could not delete existing results; aborted." +elif ! rm -f -- "$pdfdir/"*.* ; then + error "Could not delete existing PDFs; aborted." +fi + +resize_percent=$((100/simplify)) + +i=1 +rv=0 + +while read -r jpg ; do + renamed=$(printf "%02d" "$i").jpg + + if cp "$jpg" "$indir/$renamed" ; then + info "Copied \"$jpg\" to \"$renamed\"." + else + warning "Could not copy \"$jpg\" to \"$renamed\"." + rv=1 + fi + + i=$((i+1)) +done < <(ls --reverse --sort time -- "$origdir/"*.jpg) + +if [[ $rv -ne 0 ]] ; then + error "One or more errors during input file naming; aborted." "$rv" +fi + +for jpg in "$indir/"*.jpg ; do + base=$(basename "$jpg" .jpg) + tmp1="$tmpdir/$base.tmp1.png" + tmp2="$tmpdir/$base.tmp2.png" + com="$tmpdir/$base.com.png" + trimmed="$tmpdir/$base.trimmed.png" + inf="$tmpdir/$base.txt" + out="$outdir/$base.png" + + if ! convert \ + "$jpg" \ + -colorspace RGB \ + -sigmoidal-contrast "$sigmoidal_contrast_trim" \ + -resize "$resize_percent%" \ + -colors "$colors" \ + -morphology "$morphology" "$morphology_shape" \ + "$tmp1" + then + warning "Could not create test image \"$tmp1\"; skipped." + rv=1 + continue + fi + + draw=() + v=255 + + while read -r primitive ; do + draw+=("-fill" "rgb($v,$v,$v)" "-draw" "$primitive") + v=$((v-2)) + done < <( + convert \ + "$tmp1" \ + -define connected-components:verbose=true \ + -define connected-components:exclude-header=true \ + -define connected-components:sort-order=increasing \ + -define connected-components:mean-color=true \ + -define connected-components:area-threshold="$area_treshold" \ + -virtual-pixel None \ + -connected-components "$connected_components" \ + -auto-level \ + "$com" | \ + perl -e ' + while(<>){ + chomp; + next unless /(\d+)x(\d+)\+(\d+)\+(\d+)/; + printf + STDERR + "DEBUG: component: $_\n"; + printf + "rectangle %d,%d,%d,%d\n", + $1, $2, $1+$3, $2+$4; + } + + ' | \ + sort | \ + uniq + ) + + printf "DEBUG: connected components in \"%s\":" "$tmp1" + for d in "${draw[@]}" ; do + printf " \"%s\"" "$d" + done + printf "\n" + + if ! convert \ + "$tmp1" \ + -fill black -colorize 100 \ + "${draw[@]}" \ + "$tmp2" + then + warning "Could not convert \"$tmp1\" to \"$tmp2\"; skipped." + rv=1 + continue + elif ! convert \ + "$tmp2" \ + -trim info: \ + > "$inf" + then + warning "Could not determine trim info from \"$tmp2\"; skipped." + rv=1 + continue + fi + + if "$keep_tmpfiles" ; then + if ! convert \ + "$tmp2" \ + -trim \ + "$trimmed" + then + warning "Could not test trim \"$tmp2\"; skipped." + rv=1 + continue + fi + fi + + # upscale crop area from smaller temporary picture sizes + crop=$(simplify=$simplify perl -MEnv -e ' + while(<>) { + chomp(); + s/(\d+)/$1*${simplify}/eg; + /(\d+)x(\d+) \d+x\d+\+(\d+)\+(\d+)/ && do { + print $1."x".$2."+".$3."+".$4; + } + } + ' < "$inf") + + if ! "$keep_tmpfiles" ; then + if ! rm -f -- "$tmp1" "$tmp2" "$trimmed" "$inf" ; then + warning "Could not remove temporary files in \"$dir/tmp\"." + rv=1 + fi + fi + + info "Processing $base: crop=$crop ..." + + if ! convert \ + "$jpg" \ + -crop "$crop" \ + -sigmoidal-contrast "$sigmoidal_contrast" \ + +dither -posterize "$posterize" \ + "$out" + then + warning "Could not process \"$jpg\"; skipped." + rv=1 + continue + fi +done + +if [[ $rv -ne 0 ]] ; then + error "One or more errors during image conversion; aborted." "$rv" +fi + +for png in "out/"*.png ; do + info "Processing \"$png\" ..." + + read -r width height < <( + identify -verbose "$png" | \ + perl -ne '/Geometry: (\d+)x(\d+)/ && print "$1 $2"' + ) + + if [[ -z $width ]] || [[ -z $height ]] ; then + warning "Could not identify width or height of \"$png\"; skipped." + rv=1 + continue + elif [[ $width -gt $height ]] ; then + backdrop=template/a4paper/landscape.pdf + jam_landscape=--landscape + else + backdrop=template/a4paper/portrait.pdf + jam_landscape=--no-landscape + fi + + base=$(basename "$png" .png) + pdf=tmp/$base.pdf + jammed=tmp/$base-pdfjam.pdf + backdropped=tmp/$base.backdropped.pdf + + if ! convert "$png" "$pdf" ; then + warning "Could not convert \"$png\" to PDF; skipped." + rv=1 + continue + elif ! pdfjam \ + --quiet \ + --outfile tmp \ + --paper "$paper" \ + "$jam_landscape" \ + --scale "$scale" \ + --offset "$offset" \ + "$pdf" + then + warning "Could not align \"$pdf\"; skipped." + rv=1 + continue + elif ! pdftk \ + "$jammed" \ + stamp "$backdrop" \ + output "$backdropped" + then + warning "Could not watermark \"$pdf\"; skipped." + rv=1 + continue + fi +done + +input=() + +while read -r pdf ; do + input+=("$pdf") +done < <(ls -- "$tmpdir/"*.backdropped.pdf) + +if ! pdftk "${input[@]}" cat output "$result" ; then + warning "Could not concatenate \"$result\"." + rv=1 +elif ! rm -f -- "tmp/"*.pdf ; then + warning "Could not remove tempfiles in \"$dir/tmp\"." + rv=1 +fi + +if [[ $rv -ne 0 ]] ; then + error "One or more errors during PDF generation; aborted." "$rv" +fi + From 0d693f3be8dc68ab531bb2b452eccda898066a1a Mon Sep 17 00:00:00 2001 From: Tilman Kranz Date: Sun, 10 Dec 2023 13:59:39 +0100 Subject: [PATCH 3/7] remove ignorefile --- template/.gitignore | 1 - 1 file changed, 1 deletion(-) delete mode 100644 template/.gitignore diff --git a/template/.gitignore b/template/.gitignore deleted file mode 100644 index 644844a..0000000 --- a/template/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*/*.svg From 5d7c97c22e7d44db7ccb1d719141ad52f27edbde Mon Sep 17 00:00:00 2001 From: Tilman Kranz Date: Sun, 10 Dec 2023 13:59:50 +0100 Subject: [PATCH 4/7] add missing template --- template/a4paper/portrait.svg | 131 ++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 template/a4paper/portrait.svg diff --git a/template/a4paper/portrait.svg b/template/a4paper/portrait.svg new file mode 100644 index 0000000..4445b17 --- /dev/null +++ b/template/a4paper/portrait.svg @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + ENTERPRISELOGO + Copyleft 2023 tk-sls.de +CC-BY-SA Attribution-ShareAlike 3.0 Unported + Generic Title Text + + From cad9979d7b4b70976b287a9e44a201da475e060d Mon Sep 17 00:00:00 2001 From: Tilman Kranz Date: Sun, 10 Dec 2023 14:00:07 +0100 Subject: [PATCH 5/7] new installation procedure --- Makefile | 24 ++++++++++++++++++++++++ run.sh => photos2pdf | 15 +++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 Makefile rename run.sh => photos2pdf (96%) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..384eee5 --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +NAME=photos2pdf +DESTDIR= +PREFIX=/usr +INSTALL=install + +BINDIR=$(PREFIX)/bin +LIBDIR=/var/lib/$(NAME) +TEMPLATEDIR=$(LIBDIR)/template + +.PHONY: all install-bin install-template install + +all: + @echo "Use \"sudo $(MAKE) install\" to install $(NAME)" + +install-bin: + $(INSTALL) -d -m 0755 "$(BINDIR)" + $(INSTALL) -m 0755 "$(NAME)" "$(BINDIR)/$(NAME)" + +install-template: + $(INSTALL) -d -m 0755 "$(DESTDIR)$(LIBDIR)" + $(INSTALL) -d -m 0755 "$(DESTDIR)$(TEMPLATEDIR)" + tar cf - -C template . | (cd "$(DESTDIR)$(TEMPLATEDIR)" && tar xf -) + +install: install-bin install-template diff --git a/run.sh b/photos2pdf similarity index 96% rename from run.sh rename to photos2pdf index 4f1a6ea..c51b184 100755 --- a/run.sh +++ b/photos2pdf @@ -41,6 +41,9 @@ offset="1cm 3cm" # Factor to scale image by before placing in page scale=0.75 +# PDF backdrop template directory +templatedir=/var/lib/photos2pdf/templates + # Filename of complete result PDF result="pdf/result.pdf" @@ -77,7 +80,7 @@ if [[ -z $dir ]] ; then error "Usage: $0 DIR" fi -origdir=$(dirname "$(readlink -f "$dir")") +origdir=$(readlink -f "$dir") if [[ ! -d $origdir ]] ; then error "Directory not found: $dir ($origdir)" @@ -286,17 +289,17 @@ for png in "out/"*.png ; do rv=1 continue elif [[ $width -gt $height ]] ; then - backdrop=template/a4paper/landscape.pdf + backdrop="$templatedir/a4paper/landscape.pdf" jam_landscape=--landscape else - backdrop=template/a4paper/portrait.pdf + backdrop="$templatedir/a4paper/portrait.pdf" jam_landscape=--no-landscape fi base=$(basename "$png" .png) - pdf=tmp/$base.pdf - jammed=tmp/$base-pdfjam.pdf - backdropped=tmp/$base.backdropped.pdf + pdf="$tmpdir/$base.pdf" + jammed="$tmpdir/$base-pdfjam.pdf" + backdropped="$tmpdir/$base.backdropped.pdf" if ! convert "$png" "$pdf" ; then warning "Could not convert \"$png\" to PDF; skipped." From 833dbc798c44c9239014405929676f52b562d612 Mon Sep 17 00:00:00 2001 From: Tilman Kranz Date: Sun, 10 Dec 2023 23:14:02 +0100 Subject: [PATCH 6/7] exclude SVGs from installation --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 384eee5..15fbdc4 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,6 @@ install-bin: install-template: $(INSTALL) -d -m 0755 "$(DESTDIR)$(LIBDIR)" $(INSTALL) -d -m 0755 "$(DESTDIR)$(TEMPLATEDIR)" - tar cf - -C template . | (cd "$(DESTDIR)$(TEMPLATEDIR)" && tar xf -) + tar cf - -C template --exclude "*.svg" . | (cd "$(DESTDIR)$(TEMPLATEDIR)" && tar xf -) install: install-bin install-template From 77f79038da9d1082f7fd069f9f81743f24135b78 Mon Sep 17 00:00:00 2001 From: Tilman Kranz Date: Sun, 10 Dec 2023 23:14:24 +0100 Subject: [PATCH 7/7] commandline parser --- photos2pdf | 163 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 124 insertions(+), 39 deletions(-) diff --git a/photos2pdf b/photos2pdf index c51b184..6a63e11 100755 --- a/photos2pdf +++ b/photos2pdf @@ -28,8 +28,7 @@ sigmoidal_contrast="45,50%" # Number of colors result images are quantized to posterize=6 -# Keep intermediate images after processing (note that they will be removed in -# any case at the next run of this script) +# Keep intermediate images after processing keep_tmpfiles=true # Paper size of all pages @@ -42,10 +41,13 @@ offset="1cm 3cm" scale=0.75 # PDF backdrop template directory -templatedir=/var/lib/photos2pdf/templates +templatedir=/var/lib/photos2pdf/template # Filename of complete result PDF -result="pdf/result.pdf" +result_filename="result.pdf" + +# Directory of original files to process (initially unset) +dir= ## # Functions @@ -71,26 +73,127 @@ info() { log INFO "$1" } +print_help() { + cat << 'EOF' +photos2pdf +========== + +Description +----------- +Trim and brighten JPGs, produce PDF containing one photo per page. + +Usage +----- +```shell +photos2pdf [OPTION ...] DIR +``` + +Arguments +--------- +* `DIR`: Directory containing the original photos. + +Options +------- +* `--simplify INT`: Before morphology analysis, reduce + image dimensions by this factor + (default: 2). +* `--morphology STRING`: Morphology to apply for trimming + (default "Open:6"). +* `--morphology-shape STRING`: Shape of morphology to apply for + trimming (default: "Disk"). +* `--colors INT`: Number of colors images are quantized + to for component detection (default: 4). +* `--connected-components INT`: Neighbors to evaluate when detecting + connected components (default: 8). +* `--area_treshold INT`: Area treshold for connected components + detection (default: 1000). +* `--sigmoidal-contrast-trim STRING`: Sigmoidal contrast adjustment + used when trimming (default: "30,30%"). +* `--sigmoidal-contrast STRING`: Sigmoidal contrast adjustment visible + in result images (default: "45,50%"). +* `--posterize INT`: Number of colors result images are + quantized to (default: 6). +* `--keep-tmpfiles true|false`: Keep temporary files (default: false). +* `--paper STRING`: PDF page size (default: "a4paper"). +* `--offset STRING`: Offset in page where image should be + placed (default: "1cm 3cm"). +* `--scale FLOAT`: Factor to scale image by before placing + in page (default: 0.75). +* `--templatedir STRING`: PDF backdrop directory (default: + "/var/lib/photos2pdf/template"). +* `--result-filename STRING`: Filename of complete result PDF + (default: "result.pdf"). +EOF +} + ## # Arguments -dir=$1 +i=1 +options_done=false -if [[ -z $dir ]] ; then - error "Usage: $0 DIR" -fi +while [[ $i -le $# ]] ; do + arg=$(eval "echo \$$i") -origdir=$(readlink -f "$dir") + if ! "$options_done" ; then + case "$arg" in + -h|--help) + print_help + exit 0 + ;; + --simplify| \ + --morphology| \ + --morphology-shape| \ + --colors| \ + --connected-components| \ + --area-treshold| \ + --sigmoidal-contrast-trim| \ + --sigmoidal-contrast| \ + --posterize| \ + --keep-tmpfiles| \ + --paper| \ + --offset| \ + --scale| \ + --templatedir| \ + --result-filename) + var=$(echo "$arg" | sed -e 's|^\-\-||;s|\-|_|g;') + i=$((i+1)) + arg=$(eval "echo \$$i") + eval "$var=\"$arg\"" + i=$((i+1)) + continue + ;; + --) + options_done=true + i=$((i+1)) + continue + ;; + -*) + error "Unknown option \"$arg\"; aborted." + ;; + esac + fi -if [[ ! -d $origdir ]] ; then - error "Directory not found: $dir ($origdir)" -fi + case "$arg" in + *) + [[ -n $dir ]] && error "Only one input directory can be specified; aborted." + dir=$arg + i=$((i+1)) + ;; + esac +done + +[[ -z $dir ]] && error "Usage: $0 [OPTION ..] DIR" ## # Main Program job_id=$(printf "%s" "$origdir" | sha256sum | cut -d" " -f1) +origdir=$(readlink -f "$dir") + +[[ -d $origdir ]] || error "Directory $dir not found; aborted." + if [[ -n $TMP ]] ; then tmp_base=$TMP/photos2pdf/$job_id elif [[ -n $XDG_RUNTIME_DIR ]] ; then @@ -99,10 +202,6 @@ else tmp_base=/tmp/photos2pdf/$job_id fi -if ! mkdir -p "$tmp_base" ; then - error "Could not create temporary workign directory $tmp_base; aborted" -fi - indir="$tmp_base/in" tmpdir="$tmp_base/tmp" outdir="$tmp_base/out" @@ -189,9 +288,6 @@ for jpg in "$indir/"*.jpg ; do while(<>){ chomp; next unless /(\d+)x(\d+)\+(\d+)\+(\d+)/; - printf - STDERR - "DEBUG: component: $_\n"; printf "rectangle %d,%d,%d,%d\n", $1, $2, $1+$3, $2+$4; @@ -202,12 +298,6 @@ for jpg in "$indir/"*.jpg ; do uniq ) - printf "DEBUG: connected components in \"%s\":" "$tmp1" - for d in "${draw[@]}" ; do - printf " \"%s\"" "$d" - done - printf "\n" - if ! convert \ "$tmp1" \ -fill black -colorize 100 \ @@ -250,13 +340,6 @@ for jpg in "$indir/"*.jpg ; do } ' < "$inf") - if ! "$keep_tmpfiles" ; then - if ! rm -f -- "$tmp1" "$tmp2" "$trimmed" "$inf" ; then - warning "Could not remove temporary files in \"$dir/tmp\"." - rv=1 - fi - fi - info "Processing $base: crop=$crop ..." if ! convert \ @@ -307,7 +390,7 @@ for png in "out/"*.png ; do continue elif ! pdfjam \ --quiet \ - --outfile tmp \ + --outfile "$tmpdir" \ --paper "$paper" \ "$jam_landscape" \ --scale "$scale" \ @@ -334,15 +417,17 @@ while read -r pdf ; do input+=("$pdf") done < <(ls -- "$tmpdir/"*.backdropped.pdf) -if ! pdftk "${input[@]}" cat output "$result" ; then - warning "Could not concatenate \"$result\"." - rv=1 -elif ! rm -f -- "tmp/"*.pdf ; then - warning "Could not remove tempfiles in \"$dir/tmp\"." +if ! pdftk "${input[@]}" cat output "$pdfdir/$result_filename" ; then + warning "Could not concatenate \"$result_filename\"." rv=1 +elif ! "$keep_tmpfiles" ; then + if ! rm -f -- "$tmp_base" ; then + warning "Could not remove temporary files." + rv=1 + fi fi if [[ $rv -ne 0 ]] ; then - error "One or more errors during PDF generation; aborted." "$rv" + error "One or more errors; aborted." "$rv" fi