For a given set of images with weights (these weights can be assigned arbitrarily), create a single row. Find the average area / weight. Create the row again, this time adjusting images that are too large by attempting to fit them into a cell with neighboring images that are also too large.
Next, take the width/height of the single row and calculate how many rows the image set should be split into to match the target ratio. Break the single row up into that many rows, that many -1, -2, +1, and +2, and hold onto those configurations and their fitness values.
Repeat the 2 steps but making columns instead of rows.
$ picgrid-compose -layouter borce -page-style hover x-rdf-subject:urn:bitprint:YRLZROF2ZKR5GCAUZ7OBMFWG2NCIO3MB.5ILYDI7K3FLR2YBENH477HYHAINKTMNTWLTGDFA Exception in thread "main" java.lang.AssertionError: assertion failed: Cell width is <= 0: togos.picgrid.layout.LayoutCell@1ae53e9 at scala.Predef$.assert(Predef.scala:179) at togos.picgrid.layout.AutoSpacingLayouter$$anonfun$layout$1.apply(Layouter.scala:99) at togos.picgrid.layout.AutoSpacingLayouter$$anonfun$layout$1.apply(Layouter.scala:98) at scala.collection.immutable.List.foreach(List.scala:318) at togos.picgrid.layout.AutoSpacingLayouter.layout$4348ff2d(Layouter.scala:98) at togos.picgrid.Gridifier.gridify$35eef3cf(Gridifier.scala:57) at togos.picgrid.Gridifier.gridifyDir$35eef3cf(Gridifier.scala:84) at togos.picgrid.Gridifier.gridifyDir(Gridifier.scala:106) at togos.picgrid.app.ComposeCommand$.main(ComposeCommand.scala:175) at togos.picgrid.app.PicGridCommand$.main(PicGridCommand.scala:166) at togos.picgrid.app.PicGridCommand.main(PicGridCommand.scala)
This seems to be a trouble with the ‘borce’ layouter, because when using ‘rowly’…
$ picgrid-compose -layouter rowly -page-style hover x-rdf-subject:urn:bitprint:YRLZROF2ZKR5GCAUZ7OBMFWG2NCIO3MB.5ILYDI7K3FLR2YBENH477HYHAINKTMNTWLTGDFA urn:bitprint:6W4PVKPFENWMOKGXCTD5I7WVTFE7NDIG.BTJTX7P4CC4UXLEZH3CL6K5PAW37NLUICWYMZUY
e.g. lots of these pictures. Let’s pick on this one in particular because it’s landscape so I figure we won’t be worrying about rotation.
Possibilities:
- imagemagick fails to squish things down that small
- java fails to load the squished images
How to run commands in the docker container?
Here’s picgrid-compose
from TOGoSUtils:
if [ -z "${ccouch_repo_dir+x}" ] ; then
echo "Please set ccouch_repo_dir" >&2
exit 1
fi
if [ -z "${picgrid_docker_image_name+x}" ] ; then
picgrid_docker_image_name=togos/picgrid:latest
fi
exec docker run \
-v "$ccouch_repo_dir":/.ccouch \
"$picgrid_docker_image_name" compose \
-datastore /.ccouch/data/picgrid \
-ms-datasource /.ccouch/data \
-page-style hover \
-layouter multifit:1024x768 \
-function-cache-dir /.ccouch/cache/picgrid \
"$@"
I think we gotta add -it --entrypoint /bin/bash
.
So maybe like…
docker run -v /home/tog/.ccouch:/.ccouch -it --entrypoint /bin/sh togos/picgrid:latest
Amd then what command will do the resizing, huh…
infile.getPath(),
"-filter",filter,
"-thumbnail",(newWidth+"x"+newHeight+">"),
"-quality","85",
outFile.getPath()
So like
mkdir -p /.ccouch/temp
/usr/bin/convert /.ccouch/data/pictures/ZM/ZMBXCX4RTE3JL743IQOCFZBNJ3PDY2WY -filter Box -thumbnail 41x29 -quality 85 /.ccouch/temp/zmbx-41x29.jpg
Result: a 913-byte file that opens just fine in Firefox.
So based on this small bit of evidence, maybe the problem is not converting to the thumbnail.
PicGrid also uses imagemagick to compose the compound images, using a command like…
output_image_size=128x128
input_image=xc:black
/usr/bin/convert -filter Box -size $output_image_size $input_image \
-draw "image over 88,35 41,29 '/.ccouch/temp/zmbx-41x29.jpg'" \
/.ccouch/temp/composite.jpg
It will actually do that in multiple passes, writing a new JPG each time, to handle very large argument strings. Weird and not great!
Anyway, the result of the above command is a 1448-byte file that looks like you’d expect.
What if we give it a bad input path?
output_image_size=128x128
input_image=xc:black
/usr/bin/convert -filter Box -size $output_image_size $input_image \
-draw "image over 88,35 41,29 '/.ccouch/temp/lololol.jpg'" \
/.ccouch/temp/composite-badinput.jpg
Result:
convert: unable to open image '/.ccouch/temp/lololol.jpg': No such file or directory @ error/blob.c/OpenBlob/3497. convert: non-conforming drawing primitive definition `image' @ error/draw.c/RenderMVGContent/4406.
And it exits with status 1. It did create a file, but it’s just black where we tried to paste that nonexistent file, not a gray rectangle.
What if we give it the good input, but without the .jpg extension?
output_image_size=128x128
input_image=xc:black
/usr/bin/convert -filter Box -size $output_image_size $input_image \
-draw "image over 88,35 41,29 '/.ccouch/temp/zmbx-41x29'" \
/.ccouch/temp/composite-noext.jpg
Result: Works as you’d expect.
Can I shed light on all this by logging all commands run?
[2021-05-17T16:21:25-05:00] Build a new togos/picgrid:dev (9300dc2f4281) that dumps all commands being run.
I should probably add a -debug
option for that sort of thing so I don’t have to build new images.
So to try it out…
docker run \
-v "/home/tog/.ccouch":/.ccouch \
togos/picgrid:dev compose \
-datastore /.ccouch/data/picgrid \
-ms-datasource /.ccouch/data \
-page-style hover \
-layouter multifit:1024x768 \
x-rdf-subject:urn:bitprint:YC5EB64KSX4R7CD7MWJSMYGK7JRMPPGZ.QNKVYTK6UEPLMMUWNSOMARGWU7AF3RYCJBP3FHQ
Dumping to ./doc/20210517-commands.txt
Okay what the hell is -fKilter
, huh?
$ "/usr/bin/convert" "/.ccouch/data/pictures/RA/RACF7T5QX5XF2HOQQLNZPKYJY3BN22PC" "-fKilter" "Box" "-thumbnail" "22x31^" "-gravity" "Center" "-extent" "22x31" "-quality" "85" "/.ccouch/data/picgrid/.temp-451198785-2136187886-167414312.jpg"
But good thing it says “fKilter” because I can grep for it and find that this is being done by ImageMagickCropResizer, not ImageMagickResizer. And when it fails, I DRAW THOSE GRAY RECTANGLES! Oy.
Let’s remove that “K” and see if things work better.
Also I’m making debugging a runtime-configurable thing.
src/main/scala/togos/picgrid/CommandLineExecutor.scala:3: warning: imported `Logger' is permanently hidden by definition of object Logger in package picgrid import togos.picgrid.Logger
I guess Scala doesn’t like it when you import a thing that’s already in the current package.
Anyway.
Successfully built f021d1701154 Successfully tagged togos/picgrid:dev make: Leaving directory '/home/tog/proj/PicGrid/docker'
So now running…
docker run \
-v "/home/tog/.ccouch":/.ccouch \
togos/picgrid:dev compose \
-datastore /.ccouch/data/picgrid \
-ms-datasource /.ccouch/data \
-page-style hover \
-layouter multifit:1024x768 \
x-rdf-subject:urn:bitprint:YC5EB64KSX4R7CD7MWJSMYGK7JRMPPGZ.QNKVYTK6UEPLMMUWNSOMARGWU7AF3RYCJBP3FHQ \
>doc/20210517T16-f021d1701154-commands.txt 2>&1
Yay that fixed it! And here are the commands it ran.