How to concatenate icons into a single image with ImageMagick? - graphics

I want to use CSS sprites on a web site instead of separate image files, for a large collection of small icons that are all the same size. How can I concatenate (tile) them into one big image using ImageMagick?

convert works much better than montage. It arranges images vertically or horizontally and keeps png transparency.
convert *.png -append sprites.png (append vertically)
convert *.png +append sprites.png (append horizontally)

From the page you linked, 'montage' is the tool you want. It'll take a bunch of images and concatenate/tile them into a single output. Here's an example image I've made before using the tool:
(source: davr.org)

You are looking for:
montage -background transparent -geometry +4+4 *.png sprite.gif

I like this script for automatical sprite/css generation.
"Building CSS sprites with Bash & Imagemagick"
article copy in Waybackmashine https://web.archive.org/web/20150529041037/http://jaymz.eu/blog/2010/05/building-css-sprites-with-bash-imagemagick
script copy http://blog.kupriyanov.com/2011/01/solvedbuilding-css-sprites-with-bash.html

Related

Resizing does not respect resolution specification

I've got a 16x512 image comprised of 16x16 images. I want to seperate them, individually scale each one down to 16x8, then put them all back into their full 16x512. I've got a basic idea, but I'm having trouble executing it.
Using the commands from unix stackexchange, I split by file by using convert -crop 16x16 my_image.png crop-%d.png, which yields 32 images (512 / 16 == 32). My next step was where trouble has started. From askubuntu, I found the command mogrify -resize 16x8 crop-*.png, however this does not yield 16x8 images, but rather 8x8, which I do not want. Furthermore, this post on stackoverflow gives me the command for merging these images, which is convert crop-*.png -append my_image_cropped.png, however it does not yield a 16x512 like I want, but rather 8x256 (the 8 is due to the previous bug, but I still want a height of 512, not 256).
What do I need to accomplish my goals? The image in question can be found on imgur.
Edit: Here are some images which will describe the basic idea
The full image:
Both 16x16 and 16x8 side by side
The finalized image, basically the 16x8 will sit in the 16x16 area (right at the bottom part, that is essential), but won't fully fill it.
I am not sure I understand what you want to do. But if you resize 16x8, Imagemagick will keep aspect ratio. If you want to force it to be exactly 16x8 and can accept distortion, then use the ! flag. But you then say you want to put the 32 pieces back to form 16x512, but the resize will make it 16x256, since you have 32 image of height 8. So you have to resize again. Here is how to do that, if that is really what you want.
Create a gradient image for testing:
convert -size 16x512 gradient: grad.png
Do the processing:
convert grad.png -crop 16x16 -resize 16x8! -append -resize 16x512! newgrad.png
Note that proper Imagemagick syntax reads the input first.
ADDITION:
Given your new information in your comment, try this:
convert grad.png -crop 16x16 -resize 16x8 -gravity northwest -background none -extent 16x16 -append newgrad.png
Change the background color as desired and the gravity setting as desired for positioning.

ImageMagic renders image with black background

I'm converting pdf files to images with ImageMagic, everything is ok until I use -resize option, then I get image with black background. I use this command:
convert -density 400 image.pdf -resize 25% image.png
I need to use -resize option otherwise I get really large image. Is there any other option which I can use to resize image or is there option to set background in white.
That's not a Ghostscript command, You will need to find out what convert is sending to Ghostscript. As it stands I can't even be sure that your problem is with Ghostscript ,since it could easily be something that convert is doing.
Solved it by removing alpha from image, it seems imagemagic tries to apply some opacity but since jpeg doesn't allow transperency result was black background. So I found example on imagemagic website and it helped me:
convert a.pdf -background skyblue -alpha remove -alpha off a_remove.jpg

How to use imagemagick to re-size only when image is too big?

I have a bunch of screenshots of websites. I need to display thumbnails of each site on a page, so I've been re-sizing them using convert 6.6.9 like this:
convert -trim -thumbnail "200x200>" $name.png $name.thumb.png
This works fine for most images, and fit everything into a 200x200 space. However, some of the websites have very long pages, so they show up as very narrow thumbnails inside the 200px height.
I'd like to keep all the thumbnails the same width, and cut any off if they extend more than, say, 300px in height. I do need to preserve the aspect ratio though.
I've tried the following, but it doesn't seem to work in the way I expect, since it only seems to work on some of the larger images but not others:
convert $name.png -resize "200" -gravity north -crop 200x300+0+0 +repage $name.thumb.png
I think I'm misunderstanding something...
AH - found the problem. I'd forgotten to add the "-trim" option to the resize, and some images have a lot of whitespace on them.

How to write a bash script that cuts images into pieces using image magick?

I have a number of input images that contain multiple smaller images, all of them in a single row. All the contained images are the same size. So, for example, the image input.png may be 480x48 and contain 10 48x48 images, all in one row.
Using the imagemagick convert tool (or any other tool supplied with the defaul imagemagick suite), I want to write a bash script that takes an input image, the number of images to cut, and then cuts them all into individual images.
The user interaction i can do, but I've not been able to get convert to do the actual cutting. Can anyone suggest something? From reading the manual pages, i think this should work:
convert 'input.png[0x0+48+48]' output.png
but I get an error:
convert: no pixels defined in cache
tb_icons_l.png' #
magick/cache.c/OpenCache/3572.
convert: No IDATs written into file
1.png' #
coders/png.c/PNGErrorHandler/1391.
Any ideas?
I would do it like that:
convert input.png -crop 48x48 +repage +adjoin output_%02d.gif
Read more at Tile Cropping, in ImageMagick documentation.
I believe you've got the position and size swapped. Try:
convert 'input.png[48x48+0+0]' output.png
The third image would be:
convert 'input.png[48x48+96+0]' output.png
Or
convert 'input.png[48x48+0+96]' output.png

Compose multiple JPEG files without re-compression

How can I compose (adjoin) multiple JPEG files without re-compression?
I know there is jpegtran that can losslessly crop and resize JPEG images, so I wonder if there is similar tool to adjoin images lossless?
Their size is a multiple 1 MCU block (16 pixels in both directions).
Newer versions of jpegtran include lossless "crop 'n' drop" (or "cut & paste") features. Via the command line, you can use -crop to create a larger image based on one of the pieces, and -drop to paste subsequent images into the combined image. Unfortunately, multiple -drop options aren't currently supported, so jpegtran needs to be invoked once for every part.
jpegtran -outfile combined.jpg -copy all -crop ${totalWidth}x${totalHeight} part-0.jpg
jpegtran -outfile combined-tmp.jpg -copy all -drop +${xOff[1]}+${yOff[1]} part-1.jpg combined.jpg && mv combined-tmp.jpg combined.jpg
...
jpegtran -outfile combined-tmp.jpg -copy all -drop +${xOff[$n]}+${yOff[$n]} part-$n.jpg combined.jpg && mv combined-tmp.jpg combined.jpg
Your mileage may vary depending on the exact properties of the image parts.
What you want to do is certainly possible, but in order for it to be truly lossless, both images must use the same quantization tables and color subsampling option. If, for example, the 2 images come from the same source (e.g. camera), then you can be pretty sure that it would be possible. You would need to entropy-decode each MCU in both images, rearrange them the way you want and then re-entropy code them and output the JPEG bitstream. If you want to overlay one on the other or crop/merge them on non-MCU boundaries, then you hit the same problem as above and must do a full decode and re-encode.
I've used ImageMagick's composite binary to watermark a JPG with a PNG image.
Like this:
composite -tile -dissolve 15 targetimage.jpg watermark.png
You can obviously use two JPEGs to achieve what you're looking for.
Using the -quality and -sampling-factor arguments will help retain quality. There is also a -compress <type> argument, where type can by Lossless. However, ImageMagick does not recommend the use of this value as the JPEG library must be patched to support this.
It's worth investigating though if it will achieve a genuine lossless image, and you're not happy with the quality of the compress and sampling-factor arguments.

Resources