horizontal stack of polaroids?

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
pooco

horizontal stack of polaroids?

Post by pooco »

what would be the best technique to create a horizontal stack of polaroids where each overlapped the previous by about 25%?

this:

montage -size 256x256 '*.jpg' -thumbnail 128x128 -set caption '%t' -bordercolor snow -background grey20 +polaroid -set label '' -background white -geometry +1+1 -tile 10x polaroids.png

is approximately the correct "look", but i can't figure out how to collapse the space between the thumbnails.

TIA
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: horizontal stack of polaroids?

Post by fmw42 »

I am a bit puzzled by your command line. Why do you have the -size 128x128 there in front of your input images? Why is it there at all? Also what is +polaroid? Do you mean -polariod with no rotation.

To get the spacing removed you can use either -geometry +0+0 if all your images are the same size or -geometry '1x1+0+0<' if they are not and you want the space filled in. If you want overlap you can use negative values for your geometry offset. As you appear to be stacking them horizontally, then you can overlap by 10 pixels by doing -geometry -10+0. This seems to make sort of an overlap look by trimming pixels, but for my tests with 3 images each of 128x128, the result was 324x128 so about 60 pixels were removed, I.e. 10 pixels on each image side, thus 3x2x10=60.

To overlap properly (and/or with transparency), you may need to replace montage with convert ... -composite.

See:

http://www.imagemagick.org/Usage/montage/
http://www.imagemagick.org/Usage/compose/
pooco

Re: horizontal stack of polaroids?

Post by pooco »

thanks for the reply.

i'm puzzled as well, though its a nearly direct copy of the examples on this page:

http://www.imagemagick.org/Usage/montage/

looks like the -size at the beginning causes the thumbed images to wrap to the next line at some point.

looks like +polaroid is -polaroid with no rotation option, picks a random number of some sort.

i was hoping to keep this as a one liner without having to jump into perl or php, but do you think theres a clean way to give a list of files from an external source, layer them as explained, dump to a png?

otherwise, -geometry '1x1-40+0' looks to be close to what i've been trying to achieve. now i'd need to take care of the first image which has negative margin'ed itself off the canvas.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: horizontal stack of polaroids?

Post by fmw42 »

You can do your montage and then feed it with a pipe to another convert that will append the cropped part of the first image

montage .... miff:- | convert firstimage[subsection] - +append outputimage
pooco

Re: horizontal stack of polaroids?

Post by pooco »

hmm, interesting. thank you. i'll take a look at that. what i'm specifically after is traversing a tree and returning the newest 5 or so jpgs in any subdirectory, then building a little polaroid montage of those files. not sure how to do that yet.

this probably isnt ideal, but i got a working-ish line with the following:

montage -gravity center null: '*.jpg' -thumbnail 128x128 -set caption '%s' -bordercolor snow -background grey20 +polaroid -set label '' -background Transparent -geometry '1x1-40+0<' -tile 5x polaroids.png

putting null: before '*.jpg' sticks an empty tile in there, which forces the other images back onto the canvas.
pooco

Re: horizontal stack of polaroids?

Post by pooco »

looks like this grabs the 5 newest jpgs from a file tree:

ls -altr `find . -name '*.jpg' -type f -print` | tail -5

now i just need to figure out how to pipe that into that montage line... i've been trying and have no idea how
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: horizontal stack of polaroids?

Post by fmw42 »

I am no UNIX expert, but see if this works:

montage -gravity center null: $(echo `ls -altr `find . -name '*.jpg' -type f -print` | tail -5`) -thumbnail 128x128 -set caption '%s' -bordercolor snow -background grey20 +polaroid -set label '' -background Transparent -geometry '1x1-40+0<' -tile 5x polaroids.png
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: horizontal stack of polaroids?

Post by Bonzo »

If you did decide to use php you could check this out:
http://www.rubblewebs.co.uk/imagemagick ... mbined.jpg

You can use glob to read all the photos in the folder, sort then just use the last 5 images in the array.
pooco

Re: horizontal stack of polaroids?

Post by pooco »

fmw42 wrote:I am no UNIX expert, but see if this works:

montage -gravity center null: $(echo `ls -altr `find . -name '*.jpg' -type f -print` | tail -5`) -thumbnail 128x128 -set caption '%s' -bordercolor snow -background grey20 +polaroid -set label '' -background Transparent -geometry '1x1-40+0<' -tile 5x polaroids.png
didnt work. nice try, though.

if worse comes to worse i guess i could dump the filenames into a txt file and then read them from montage.. but i'd like to figure out how to do it right.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: horizontal stack of polaroids?

Post by fmw42 »

Anthony is back from vacation. Perhaps he can show you how to do this correctly. I would be interested in his response.
pooco

Re: horizontal stack of polaroids?

Post by pooco »

bump?
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: horizontal stack of polaroids?

Post by anthony »

Yes I am back..

Fred: +polaroid is an argument-less form of -polaroid that uses a random angle.

Pooco: -size is only used to speed up JPEG reading. Read the top part on the Montage examples page, or the JPEG file format examples.

Pooco: Montage will NEVER do overlaping images. Period.
It is a simple wrapped around a convert command that starts its work wned all the images have been loaded, and creates an multi-image arrays of the given images. That is all.

For overlapping the better idea is to use the techniques in IM Examples, Layers of multiple images.
http://imagemagick.org/Usage/layers/

As you probably don't know the final size of the resulting image I would suggest you use -mosaic rather than -flatten. Mosaic creates an expanding canvas for the image, so you only need to position each image by that images top left corner. However all positions must be positive, so may require special handling of the first image, or trimming of the canvas at the end. Not a good way to do things.

Better still you can use the newer -layers merge, so you don't have to try to keep all positions positive, on the 'virtual canvas'. That is the canvas will grow both in positive and negative directions, and you don't then need to 'guess' or generate an over large canvas as 'bonzo' does in his PHP script. This however will only be available in the newest IM versions.

OKAY. you will need an external loop to figure out the positions of each images top left corner.

Hmmm lets assume you want each rotated (polaroid) image positioned so that images 'center' is a fixed distance from the other images, and you have a directory of image. You also want to overlay each photo to the left of the previous photo.

Lets position the center of the first image at 0,0, and the next image at 100 pixels to the left. As these positions would be centers, we need to subtract half the images size from the postition.

we can loop and work on each individual image, then pipe it as a 'concatenated' MIFF image file format into a pipeline to the 'layering' command that will merge all the images onto the final canvas.

So here is a shell script...

Code: Select all

center=0     # current center location for the next image
offset=100      # distance to the next images center.
background=LightSteelBlue   # background canvas color
for image in *_orig.jpg
do
   # read, thumbnail, polaroid image to a temp file.
   # I used super-sampled polariod to make the result better
   # This could have been done in a previous step to this loop
   convert -size 500x500 "$image" -thumbnail 240x240 \
       -set caption '%t' -bordercolor Lavender -background black \
       -pointsize 12  -density 96x96  +polaroid  -resize 50% \
       /tmp/polaroid_series.png

   # Now gather image size, half it, and determine its virtual canvas
   # location so as to place it's center at the current position.
   xpos=`convert "$tmpfile" -format "%[fx: $center - w/2 ]" info:`
   ypos=`convert "$tmpfile" -format "%[fx: - h/2 ]" info:`

   # $ypos is always negative
   # but $xpos may be positive, in which case it needs to have a '+' sign
   xpos=`echo "+$xpos" | sed 's/+-/-/'`

   # Output the image into the pipeline for placement on canvas
   # at the position (for top-left corner) calculated
   convert -page $xpos$ypos "$tmpfile" MIFF:-

   # increment position for next image  (lets use IM for the math ;-)
   center=`convert xc: -format "%[fx: $center + $offset ]" info:`
done |
  # Now we read the pipeline of the images output from the above loop
  # and create the canvas.  Repage the virtual canvas, add some extra
  # border space and output it.
  convert -background "$background"  MIFF:- \
         -layers merge +repage \
         -bordercolor "$background" -border 5x5 result.jpg
Enjoy!

I have added the above into a script, which will appear at
http://imagemagick.org/Usage/scripts/polariod_series
in a day or two. I don't like its output handling, and will try to fix that up later.

I love the output!!!!
Image

I have to write this up in 'Layering Images' as a practical example.

As the individual images are handled seperatally, due to the need to extract and calcualte positions, you can also do other things, like use a more ordered polariod rotation control.

also as you have total control over placement you can place the first image at 0,0, but the next on the right, then on the left, then on the right, and so on. Then by adding an appropriate -compose method for the the -layers merge, you can make the first (center) image on top!

What can you come up with!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
pooco

Re: horizontal stack of polaroids?

Post by pooco »

anthony,

firstly, thank you! this is a very thorough script. awesome. i'll play around with it and post any alterations. i wanted to put this in a cron to automatically create a line of the newest uploaded images, and include that script with a flash-based image viewer i'm releasing.

montage can do overlapping images, unless i'm misunderstanding something you're saying. this line produces a very close result to what i'm talking about (it doesnt do the enlarge + reduce method to fix blurry text, though):

Code: Select all

montage -gravity center null: '*.jpg' -thumbnail 128x128 -sharpen 10 -set caption '%t' -bordercolor snow -background grey20 +polaroid -set label '' -background Transparent -geometry '1x1-40+0<' -tile 20x polaroids.png
Image

i'm using the newest IM build.

is there any way to tack on piped unix results to imagemagick bins?

i want to put the results of this

Code: Select all

ls -altr `find . -name '*.jpg' -type f -print` | tail -5
into the montage call above, in one line, if possible.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: horizontal stack of polaroids?

Post by anthony »

It is very strange that montage, created the overlaping images. Hmm looks like you are setting a negative space between the images using -geometry whcih is a very unusual and interesting effect that no one has reported before.

This is why you needed the null: at the start, to ensures an extra tile (for that overflow) was added at the start of the line.

However I would NOT relay on it as montage is NOT ment to be generating overlaping images. The only reason it is working is because IM is not checking that the inter image space is a positive number. That is you are making use of a BUG. It is not an intended feature, and could be fixed or disappear in response to reports from other users, maybe for something completely unrelated!

I'll have to make a note of in on the montage page, with an example, that way when this un-intensional feature disappears (if ever) we will know about it.

One point use -tile x1 rather than -tile 20. Also add another null: after reading in your JPEG images. The later will always generate space for 20 tiles, and will generate more lines when more that 18 photos (+ two null: spaces) are given. The former however only creates one line with enough tiles for the number of images and null: spaces given.

NOTE the position of the centers between the images will be correctly spaced, however the amount of space will be 40 pixel minus the largest polariod image generated. That makes it a lot more variable and random.

In my script the centers are fixed distances, so it is only the width of the two end images that will produce a variable image width, though the height will still be the maximum height over all the images. Much less variable.

My solution will also let you place images anywhere, relative to each other. You can even generate a spiral, arc or circle of images. The canvas will always automatically size itself to fit the images, regardless of how the images are placed, or the amount of space or overlay you use.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
pooco

Re: horizontal stack of polaroids?

Post by pooco »

i'd still like to figure out a one-liner, but i do like the control in your script. definitely.

unless you beat me to it, i'd like to modify your script to be more organic looking. i think part of the appeal with drop shadowed polaroid frames is that theyre semi-natural. it would make sense to extend that idea and give more randomized placement (still mostly controlled) to each photo. randomize both the vertical placement and horizontal crowding. i wasn't going to bother with any of that in the crowded montage line, but your shell script opens that possibility up. i'd also probably make the labels contain the exif date, defaulting to the file timestamp if unavailable. perhaps with a handwriting font. ideally, i'd like to put a dirt-map to stain the white frames a little, but that's for another day.

so i'm guessing theres no way to pass in a file list from unix pipes?

thank you again for the thorough solution and answers, youve been very extremely helpful.
Post Reply