Informal but coherent montage

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?".
Post Reply
theuser
Posts: 3
Joined: 2012-06-28T18:03:58-07:00
Authentication code: 13

Informal but coherent montage

Post by theuser » 2012-07-03T08:54:36-07:00

Hello people.

Can anyone tell me if I can create something like this with some of the command line utilities?

So far, I've used this: "montage -mode concatenate 1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png" but it's not exactly what I'm looking for.

Image

User avatar
fmw42
Posts: 22468
Joined: 2007-07-02T17:14:51-07:00
Location: Sunnyvale, California, USA

Re: Informal but coherent montage

Post by fmw42 » 2012-07-03T10:53:47-07:00

I do not think montage can deal with arbitrary sized images and automatically place them to fit or overlap. Though I am not an expert on montage.

I think what you may need to do is use -page to set where each image is to be placed and then use -flatten. see
http://www.imagemagick.org/Usage/layers/#flatten

I think Anthony has some ideas for improving montage in IM 7 under pre-alpha development. But that will likely come later.

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

Re: Informal but coherent montage

Post by anthony » 2012-07-03T21:39:17-07:00

Tricky.

As a starting idea for the method...
  • I would first add images to the corners. (hardest position to hit with a random location).
  • Now randomly add images at first, until you reach say a 75% coverage of the background. Ensureing you only add images at a position that actually cover some amount of the background.
  • After that add new images centered over any background not yet covered.
    (their was a discussion topic to find large empty spaces using the morphology disance functions.)
  • Once you have the list of images and positions, that provides complete coverage. I would then take that list, randomise the exact order in which images are layered, and flatten them all in the new random order.
It actually would make a nice 'layout' method.

Variations to this to always use the distance technique for all positioning, so that if posible new images are added at the appropriate distance from background edges, otherwise in the center of the background area left (to cover it). That way images are first added 'adjacent' to corners, edges, and large spaces, first. But I would pick which of the possible positions randomly (to avoid a top-down package - whcih may be another option).

Note that in this position determination, images do not actually need to be placed, only have the background masked.

The above method would even handle 'shaped' images, though 'placement' may be a little tricky, due to the chance the shape leaves holes back to the background, that needs another image to cover :-)

That background masking file can also be used to generate a website 'which image' hit map, (Can't seem to find the reference!)
Basically get a web user 'hit location' -> hit map color lookup -> color to image -> show info about that image.
(this is now discussed in the topic:
Create a type of image map dynamicaly with the image
viewtopic.php?f=1&t=21365
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
http://www.imagemagick.org/Usage/

Bonzo
Posts: 2893
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Informal but coherent montage

Post by Bonzo » 2012-07-04T00:00:55-07:00

That background masking file can also be used to generate a website 'which image' hit map, (Can't seem to find the reference!)
That is the method I was using on my old gallery index page using php and an extra image with the blocks of colour for the map and imagecolorat

Looks like I have removed the example from my website but Iif the OP is interested I could see if I could find it.

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

Re: Informal but coherent montage

Post by anthony » 2012-07-04T00:29:59-07:00

Bonzo wrote:
That background masking file can also be used to generate a website 'which image' hit map, (Can't seem to find the reference!)
That is the method I was using on my old gallery index page using php and an extra image with the blocks of colour for the map and imagecolorat

Looks like I have removed the example from my website but Iif the OP is interested I could see if I could find it.
I thought it was you, but as I could not find it, I could not verify it. Perhaps you like to write up the technique for others to follow it more clearly.

Your 'map image' technique I thought was a great way to get around the 'shape' or boundary problems of web 'imagemaps'.

When 'layouts' do become more usable. I'd like IM to generate both the 'montage' image and the 'map image', as well as a more normal 'map' image, even though this may have overlapping areas, in some layouts (like this one).
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
http://www.imagemagick.org/Usage/

Bonzo
Posts: 2893
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Informal but coherent montage

Post by Bonzo » 2012-07-04T14:19:55-07:00

I have found my old code and will write some code with notes as you suggest Anthony.

I think it is a neat way to create and use image maps as well.

One thing I notice though is the colour selected can not be exact but has to have some tolerance which I pressume is due to the way ImageColorAt works.
According to the php website:
If PHP is compiled against GD library 2.0 or higher and the image is a truecolor image, this function returns the RGB value of that pixel as integer. Use bitshifting and masking to access the distinct red, green and blue component values
Currently I have no idea what " bitshifting and masking " means but for a blue I had to use:

Code: Select all

elseif ($rgb > '131' & $rgb < '167')
This cuts down the amount of colours that can be used.

I wonder if IM can get the colour quickly and not rely on ImageColorAt as we can pass the coordinates of the pixel to IM to find the colour? Anyway I will write an example and that can be looked into later.

User avatar
fmw42
Posts: 22468
Joined: 2007-07-02T17:14:51-07:00
Location: Sunnyvale, California, USA

Re: Informal but coherent montage

Post by fmw42 » 2012-07-04T14:59:50-07:00

convert rose:[1x1+10+10] -format "%[fx:round(255*u.b)]" info:
57

or

convert rose:[1x1+10+10] -format "%[fx:round(255*u.r)],%[fx:round(255*u.g)],%[fx:round(255*u.b)]" info:
72,64,57

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

Re: Informal but coherent montage

Post by anthony » 2012-07-04T19:22:00-07:00

Bonzo wrote:One thing I notice though is the colour selected can not be exact but has to have some tolerance which I pressume is due to the way ImageColorAt works.
According to the php website:
If PHP is compiled against GD library 2.0 or higher and the image is a truecolor image, this function returns the RGB value of that pixel as integer. Use bitshifting and masking to access the distinct red, green and blue component values
Currently I have no idea what " bitshifting and masking " means but for a blue I had to use:

Code: Select all

elseif ($rgb > '131' & $rgb < '167')
Example of bit shift and bit masking
Some images used color values of 5 bits red 5 green and 6 blue which forms a 16 bit color value; RRRRRGGGGGBBBBBB
See Quantization, "TrueColor 16bit Colormap"
http://www.imagemagick.org/Usage/quanti ... t_colormap

To get say the value of the 5 bits of green you would first bit shift the number down by 6 bits (to remove blue bits), then mask the lower 5 bits it to remove the red bits (NB: 31=2^5-1 )
green = (value>>6)&31
that gets a number from 0 to 31, to make it 8 bit equivalent multiply by 255/31 (NB: 255=2^8-1)

A multiply is used rather than a bit shift ( green<(8-5) ) so that the lower 3 bits also fill in, so that full green (was 31) becomes 8 bit full green (255), a bit shift up by 3 bits would generate a not-quite-full-8-bit-green of 248

See "332 Colormap" generation, for another example of bit shifting.
http://www.imagemagick.org/Usage/quantize/#332_colormap


But if the map image is grayscale, the value should be just the image index number, so that should make it a LOT easier.

If you need a 16-bit truecolor map, only generating blue values will give you 64 blue colors (8bit blue / 4 or bitshift downward by 2 ) the values of which does not need any bitshifting or masking to use!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
http://www.imagemagick.org/Usage/

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

Re: Informal but coherent montage

Post by anthony » 2012-07-04T19:24:56-07:00

Bonzo wrote:I wonder if IM can get the colour quickly and not rely on ImageColorAt as we can pass the coordinates of the pixel to IM to find the colour? Anyway I will write an example and that can be looked into later.
IM automatically converts known image file formats to its internal Quality level. So it does all the bit shifting! That of course will also ruin the actual input Truecolor value, whcih I presume you are using as an index. You would need to convert that value back to true color values to extract the image index.

If you can use grayscale imagemaps, you can aviod this true color garbage! You are after all, only interested in retrieving some value for a specific location in the imagemap.


If you want to continue tis discussion, start a new topic. I'll split these post out of this discussion to that topic.

Anyone else have comments on the original problem?
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
http://www.imagemagick.org/Usage/

User avatar
fmw42
Posts: 22468
Joined: 2007-07-02T17:14:51-07:00
Location: Sunnyvale, California, USA

Re: Informal but coherent montage

Post by fmw42 » 2012-07-04T22:03:59-07:00

You can find the placement coordinates similar to how I process my scripts, separate and multicrop, by using compare with a single pixel (say white) against a white background to locate any free space, then draw in the rectangle of the size of the image in black. Then repeat until all space is filled with black.

My thought was to follow Anthony's suggestion to make an image that was black, except for a one-pixel white boundary. Use that to fill the edges first with say red. Then when that is done convert the black to white and red to black, and fill in all the interior white parts with black. Make a list of locations found from compare. Randomize (if needed or desired). Then flatten all the images using the found coordinates in the randomized list. I assume that all the images are already sized as desired. The only issue might be that a larger image may almost totally overlap a smaller image, whether randomized or not. I have not given this too much thought, yet. So the above is just a rough idea to consider or critique.

When I get some time, I may try to script this. But Bonzo, go ahead and do your way, as I don't know when I will get around to this.

Bonzo
Posts: 2893
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Informal but coherent montage

Post by Bonzo » 2012-07-05T09:50:11-07:00

fmw42 the code I was going to write an example was for an imagemap effect - I would have no idea where to start with locating images on a canvas!
convert rose:[1x1+10+10] -format "%[fx:round(255*u.b)]" info:
57
or
convert rose:[1x1+10+10] -format "%[fx:round(255*u.r)],%[fx:round(255*u.g)],%[fx:round(255*u.b)]" info:
72,64,57
The method I used was to create the image with the photos and have another image with blocks of colour the same size and position as the photos. When the user clicks on the photo the x and y position was passed in the URL and the code checked what colour was at that position on the second image. The correct URL was selected depending on the colour value.
What I would need IM to do is lookup the pixel colour at the X and Y position; which I would have thought it could do?

Bonzo
Posts: 2893
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Informal but coherent montage

Post by Bonzo » 2012-07-05T09:57:12-07:00

Your explanation sorts of make sense to me Anthony but I would like to see it in action :)

I will get an example writen and try implimenting it then.

Bonzo
Posts: 2893
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Informal but coherent montage

Post by Bonzo » 2012-07-05T14:51:18-07:00

With the original question one simple method would be to have an array of locations and a size for each location. Then have a list of images that would be resized for each location and placed into the locations.

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

Re: Informal but coherent montage

Post by anthony » 2012-07-05T18:49:44-07:00

fmw42 wrote:The only issue might be that a larger image may almost totally overlap a smaller image, whether randomized or not. I have not given this too much thought, yet. So the above is just a rough idea to consider or critique.
yes having too much overlap is the problem with any randomised image layout.

That was why I added that images should be positioned using a distance method so its edges allign with existing images.
It would be only the last few images in the center that would then start getting serious overlap.

One way would be to complete the initial position list, then 'jiggle' each image position such so as to 're-center' that image in the background area it covers (and which is not covered by any other image (including the ones found later). That is incrementally spread out the heavy overlaps of the last few images over the whole image, to the ones with less overlap that was initially added. This however is a lot of calculation that would require a LOT of processing.

Alternativally, just place all the images in the canvas area, in a top-down way to remove all background first. Then apply that 'jiggle image position' function, to spread out the overlaps that would become common near the bottom.

NOTE: optionally images may or may not be 'jiggled' so as to be placed partly off the background canvas area, to improve the amount of overlap within the canvas area.

More options could be provided in how final image list should be layered. For example: Random, top-down, center top-most.

This is still a very complex layout technique, with lots of possibilities, But I believe I am getting an idea for how a 'general layout' operator (or command, like "montage") should work.
  1. prepare images (rotations, framing, lables, and other 'fluff')
  2. initial placement of images (for some goal, like cover background, or in rows, columns, arcs, spirals, etc)
  3. optional adjustment of placements (minimise overlap, remove excess images such as those that go off the edge)
  4. re-order the image layering (input order, top/bottom/left/right placement order, center uppermost, edge uppermost, randomize)
  5. output results....
    • flatten/mosaic/merge (resulting image for display)
    • generate imagemaps (for color index mapping)
    • generate imagemap table (color index, rectangular positions, to image name or link)
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
http://www.imagemagick.org/Usage/

Post Reply