Algorithm to pack N rectangles into a larger one - algorithm

I am writing a (JavaScript) thumbnail generator and this bit of the project involves placing the N thumbnails in regular rows and columns within a larger target space, including a border around the outside and "visually pleasing" borders between each thumbnail.
Each thumbnail is large and already scaled to turn it into a thumbnail so one approach is to change the size of each thumbnail to help fulfil the packing conditions.
Each thumbnail is of an identical size. The number of thumbnails could be anywhere from a small number (4??) to something around 100.
I have been looking for some ideas and there seem to be plenty of example code for algorithms that pack as many rectangles of different sizes into the densest possible configuration - but I haven't come across anything similar to what I am trying to do.
If anyone can point me at some code or even an algorithm, I'd be very grateful.

Related

layout algorithm for tightly-packed image thumbnails

I'm working on an image gallery and I'd like to tightly pack the image thumbnails. The thumbnails are:
different aspect ratios
available at the same source resolution (longest edge 256 pixels)
I'd like to come up with an optimal solution (will probably have to be a heuristic) that allowed me to balance:
the padding between each thumbnail (preferably constant)
the consistency of thumbnail size (preferably all the same size)
the amount of each image that gets cropped for the display (preferably none)
the proximity of images consistent with their sort order (preferably sort-neighbours will be near one another in the grid)
I think this is a variant of the rectangle packing problem.
I've found some good references: Fast Optimizing Rectangle Packing Algorithm for Building CSS Sprites
But I wanted to check with the experts to see if anyone knows of:
any established algorithms that are available publicly,
any open source libraries that implement them or
any other mathematical references or guidance that might help me produce something as good as: http://labs.tineye.com/multicolr#colors=4b669e;weights=100;
I have come up with something like this (now also with code on github)
https://mendrik.github.io/diorama/
I should add that the order will be random, and the sizes try to be uniform, but for me it was more important to fill out the entire space rather than keep the sizes consistent. You can resize the browser window to see how it works.
If your height is not fixed, there are several other options, mostly knapsack or partitioning algorithms. 2d bin backing will leave you with gaps or wont find solutions that always fit all images.
my algorithm has almost no cropping and fits always all images into the given space, provided there are enough combinations to do so. the less images the more cropping obviously.

How to implement a gapless block layout algorithm?

I'm trying to display images in a grid layout that is 4 units wide by an arbitrary number of units high.
Each image in the grid may be 1x1, 1x2, 2x1 or 2x2 units. I'm also using jQuery masonry to try and eliminate some gaps in the layout.
The size an image is displayed at (1x1, 2x2, etc.) is a "preferred" size based on its dimensions.
I'm thinking that the easiest way to eliminate gaps in the layout would be to display certain images in the layout at sizes other than their preferred size. How can I do this algorithmically, maintaining the largest number of photos that are displayed at their preferred size, while overriding for those that are determined to be necessary for a gapless layout.
A visual example; I want to turn this:
into something like what they have on this website: http://500px.com/
Just a start: I think this is an instance of bin packing which is NP-complete in the general case (see this pdf). Might be helpful to start searching for things in those terms... this is not a complete answer by any means.
The simplest thing you can do is group pairs of 1x2s together, pairs of 2x1s together, and quadruples of 1x1s together. Laying out lots of 2x2s is then easy, and only the odd-images out will need to be resized. This (or something like it) is almost certainly what 500px.com does.
I suspect this solution doesn't really jive with your "laid out left-to-right, top-to-bottom" restriction. But I'm not sure what that restriction means, exactly. Perhaps if you could make it clear what that means we could help you better.

Pack images into a larger image

There are images (literally, PNG files), they come in different sizes and need to be put together into a larger image, so that (1) they don’t overlap, and (2) the amount of unused pixels is minimal.
Can someone point me in the right direction? I can imagine that packing rectangles is nothing new, but honestly, I cannot find neither an implementation nor an algorithm for this.
This is one algorithm: Fast optimizing rectangle packing algorithm for building CSS sprites. The article includes an explanation and C# code. It also links to a paper that might be interesting.

Layout many irregular boxes so they fit on screen

I've got a list of images with dimensions for each image. I need to select and layout a group of images from that list so they fit on screen with slight overlaps, and no gaps. (gradient in the overlap to avoid a sharp transition)
I've researched 2d box packing algorithms, but they all assume that you need to use all the items, and, of course, that gaps are better than overlap.
If needed, I can downscale some or all of the images, however I can't upscale them.
Is there a good way to do this?
Maybe you could apply the 2d box packing algorithms you have researched, which assume you need all images, and just apply them using a selected group of images. This group could have been previously generated using any criteria. However, using the image's size seems adequate, because having a group of similarly-sized images eases the packing of said images. To achieve the overlapping you could use smaller dimensions for each image in the packing algorithm and then move each image of the group according to its difference in size from the packing algorithm and actual size.

Piece together several images into one big image

I'm trying to put several images together into one big image, and am looking for an algorithm which determines the placing most optimally. The images can't be rotated or resized, but the position in the resulting image is not important.
edit: added no resize constraint
Possibly you are looking for something like this: Automatic Magazine Layout.
Appearantly it's called a 'packing problem', which is something frequently used in game programming. For those interested, here are some suggested implementations:
Packing Lightmaps,
Rectangle packing and
Rectangle Placement
I created an algorithm for this ones, it's actually a variant of the NP-Hard Bin packing problem, but with a infinite bin size.
You could try to find some articles about it and try to optimize your algorithm, but in the end it will remain a brute force way to try every possibility and try to minimize the resulting bin size.
If you don't need the best solution, but just one solution, you could avoid brute forcing all the combinations. I created a program which did that once too.
Description:
Images: array of the input images
ResultMap: 2d array of Booleans
FinalImage: large image
Sort the Images array so that the largest image is at the top.
Calculate the total size of your images and initialise the ResultMap so that it's size is 1.5 times the total size of your images (you could make this step smarter for better memory usage and performance). Make the ResultMap the same size and fill it with False values.
Then add the first image in the left of your FinalImage and set all the Booleans in ResultMap true from 0,0 until ImageHeight, ImageWidth.
The ResultMap is used to quickly check if you can fit an image on the current FinalImage. You could optimize it to use a int32 and use each bit for one pixel. This will reduce memory and increase performance, because you can check 32 bit's at once (using a mask). But it will become more dificult because you'll have to think about the mask you'll need to make for the edges of your image.
Now I will describe the real loop of the "algorithm".
For each image in the array try to find a place were it would fit. You could write a loop which would look trough the ResultMap array and look for a false value and than start to see if it remains false in both directions for the size of the image to place.
If you find a place, copy the image to the FinalImage and update the correct booleans in ResultMap
If you cand find a place, increase the size of the FinalImage just enough (so look at the edges where the minimal amount of extra space is needed) and also sync that with the ResultMap
GOTO 1 :)
It's not optimal, but it can solve the problem in a reasonably optimal way (especially if there are a few smaller images to fill up the gabs in the end).
Optimal packing is hard, but there might be simplifications available to you depending on the details of your problem domain. A few ideas:
If you can carve up your bitmaps into equally sized tiles, then packing is trivial. Then, on-demand, you'd reassemble the bitmaps from the tiles.
Sort your images largest to smallest, then, for each image use a greedy-allocator to select the first available sub-rectangle that fits the image.
Use a genetic algorithm. Start with several randomly-selected layouts. Score them based on how tightly they're packed. Mix solutions from the top scoring ones, and iterate until you get to an acceptable score.
You are probably looking for SIFT
http://www.cs.ubc.ca/~lowe/keypoints/
http://user.cs.tu-http://www.cs.ubc.ca/~lowe/keypoints/.de/~nowozin/autopano-sift/technicaldetails.html
In a non-programmatical way, u can use MS Paint feature "Paste From" i.e. Paste a (JPEG) file into the mspaint image area. Using this u can arrange the individual images, and create a final big image and save it as JPEG/GIF/Raw-BMP format.
-AD.

Resources