How to batch resize PNG files with commandline on Mac? - image-resizing

I want to resize a folder of PNG images to a specified scaled size like (50%) on Mac. What is the easiest way to do that with commandline?
Thanks,

The ImageMagick command you need is mogrify if you want to do a whole directory (folder) full of images.
# First, check current sizes of PNGs
identify *png
a.png PNG 2480x3508 2480x3508+0+0 8-bit sRGB 25.4KB 0.000u 0:00.009
b-0.png[1] PNG 2480x3508 2480x3508+0+0 8-bit sRGB 2c 2.18KB 0.000u 0:00.000
b-1.png[2] PNG 2480x3508 2480x3508+0+0 8-bit sRGB 2c 2.2KB 0.000u 0:00.000
# Now reduce those puppies in half
mogrify -resize 50x50% *png
# Re-check their sizes
identify *png
a.png PNG 1240x1754 1240x1754+0+0 8-bit sRGB 1.42KB 0.000u 0:00.000
b-0.png[1] PNG 1240x1754 1240x1754+0+0 8-bit sRGB 2c 1.43KB 0.000u 0:00.000
b-1.png[2] PNG 1240x1754 1240x1754+0+0 8-bit sRGB 2c 1.46KB 0.000u 0:00.000
Updated
If you want to do fancier things, you may prefer to use a little loop:
#!/bin/bash
shopt -s nullglob
for f in *.png; do
new=${f/.png/thumb.png}
echo convert "$f" -resize 50x50% "$new"
done
So, this will loop through all PNG files and calculate a new name for each (in the variable new) and then use ImageMagick's convert to resize the images and save with the new name.
Back up your images first and if you like the way it works, remove the word echo from the second to last line to make it actually do anything rather than just tell you what it plans to do.

Just install Imagemagick then you will be able to use convert and mogrify commands which do that sort of things easily.

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.

linux convert thumbnail but move position

I have used linux convert command to successfully create thumbnails as follows:
$disposition='200x200';
$str="convert -size $disposition \"$fullPath\" -resize $disposition +profile '*' \"$fullPathThumb\"";
$result=`$str`;
However what I want to also do is "slide the sized down image some so that the upper left corner of the image is moved around, usually negative value up and negative value left, to center and crop. How would I do that? Thanks.
I am not too sure I understand your "sliding around" idea, but hopefully the following will explain how you can crop with offsets and resize. If not, please ask further questions.
Let's start with an image made of 8 blocks, each 100x100 pixels and off-square so we know which is side is which.
convert -size 100x100 \
\( xc:red xc:blue xc:green xc:black +append \) \
\( xc:cyan xc:magenta xc:yellow xc:white +append \) -append out.png
Now, we check its size is indeed 400x200:
identify out.png
out.png PNG 400x200 400x200+0+0 8-bit sRGB 8c 467B 0.000u 0:00.000
So, first we will do a simple resize, which will preserve the 2:1 aspect ratio:
convert out.png -resize 300x300 simple_resize.png
identify simple_resize.png
simple_resize.png PNG 300x150 300x150+0+0 8-bit sRGB 47c 672B 0.000u 0:00.000
Now we use the bang operator (!) to tell ImageMagick rather forcefully "Do what I said"
convert out.png -resize 300x300! simple_resize_changed_aspect.png
identify simple_resize_changed_aspect.png
simple_resize_changed_aspect.png PNG 300x300 300x300+0+0 8-bit sRGB 52c 894B 0.000u 0:00.000
And finally, we come to what is hopefully the bit you want, which is crop and resize. So let's crop an area 150 pixels wide by 100 pixels high starting 150 pixels across to the right from the top left corner and 50 pixels down from the top left corner:
convert out.png -crop 150x100+150+50 -resize 300x300 x.png
That looks right, but if we use identify we will see that ImageMagick has remembered too much about where our image came from and is considering it a part of the bigger original image:
identify x.png
x.png PNG 300x200 800x400+300+100 8-bit sRGB 30c 732B 0.000u 0:00.000
So, actually we better tell ImageMagick to reset the dimensions of the image so it is sitting on a canvas of "just the right size"... by using the +repage option on the previous command like this:
convert out.png -crop 150x100+150+50 -resize 300x300 +repage x.png
and check again
identify x.png
x.png PNG 300x200 300x200+0+0 8-bit sRGB 30c 690B 0.000u 0:00.000
That's better - probably best to use +repage whenever you crop. I hope that addresses your question, as I said, please ask further if not.

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

ImageMagick - Convert a GIF to PDF portrait(letter) on half page using convert command

I have a image of dimension 1400x800, which I need to convert to a PDF so that the PDF is in in Portrait form & contains the image in top/bottom half of the page.
I need to use ImageMagick 6.4.8 2009-09-21 as that is the only available on my production server. Cannot use Ghostscript.
Image Details
>identify sample.gif
sample.gif GIF 1400x800 1400x800+0+0 8-bit PseudoClass 256c 29.3kb
I have tried all the options that I found out & nothing works. It always converts to a Landscape with the image occupying the complete page.
Here are some of the options that I tried:
convert -bordercolor none -border 100x100 -page Letter -density 72 sample.gif -resize 792x612\! sample.pdf
convert -bordercolor none -border 100x100 -page Letter -density 72 sample.gif -resize 612x792\! sample.pdf
convert -density 72 -size 1400x800 sample.gif -page Letter -density 72 -resize 504x288 -bordercolor none -border 11%x14% sample.pdf
and many such combinations, but nothing works. I use -resize 612x792 so that its letter size, but then the image also gets stretched vertically. Is it possible to achieve what I am trying to, what options am I missing?
Note: I have to do this in a program so need a command based solution using convert.
My guess is that you are using this to print shipping labels. Either way try this
convert -size 1700x2200 xc:white sample.gif -geometry 1400x800+150+150 -composite -page Letter -quality 100 sample.pdf

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