Why does convert png->jpg blow a picture up to the original size? - imagemagick

I have a png whose width is 2551 pixels and whose height is 3578 pixels.
On this png, I use the -crop option of convert to cut out an image whose dimensions are 2362 x 3389 pixels:
convert original_2551x3578.png -crop 2362x3389+94+94 crop_2362x3389.png
This works as intended.
Then, I use convert to create a jpg:
convert crop_2362x3389.png -format jpg -flatten -background white out.jpg
I expected this command to produce a jpg with the same dimension (2362 x 3389). Much to my surprise, the produced jpg has the dimension 2551 x 3578 pixels (which is the same as the original image).
So it seems that somehow the original size is stored along with crop_2362x3389.png.
How can I use convert to convert a png into a jpg and have it keep the dimension of crop_2362x3389.png?

The reason you are seeing this is that when you do your initial crop, the image "remembers" it was part of a larger image and where in that image it used to be.
You can see this if you do your original crop and then run identify and look at the 4th field, just left of 8-bit.
convert original_2551x3578.png -crop 2362x3389+94+94 crop_2362x3389.png
You can also tell ImageMagick to "forget" it by using +repage like this:
# Repage after changing geometry to forget earlier geometry
convert original_2551x3578.png -crop 2362x3389+94+94 +repage crop_2362x3389.png
# Check IM has forgotten image used to be a part of a bigger one
identify crop_2362x3389.png
crop_2362x3389.png PNG 2362x3389 2362x3389+0+0 8-bit sRGB 256c 15.1KB 0.000u 0:00.000

Ok, I've found a solution. The geometry after the -crop parameter must be followed by a !:
convert original_2551x3578.png -crop 2362x3389+94+94! crop_2362x3389.png
This works as intended.

Related

crop image with imagemagick offset given in percentage

imagemagick's crop command supports cropping to a percentage of an image but the offset values must be specified in pixel values, e.g.:
convert image.png -crop 50%x+10+20
I want to crop with offset values x and y given in percentage of the image width, and height respectively. The pixel values can be calculated, for instance if the image size is 100x200 an offset of 10% would result in 10 and 20 respectively. Is it possible to do this calculation as part of the call to convert? Width and height are available as %w and %h at some places, but this does not work:
convert image.png -crop 50%x+(0.1*%w)+(0.1*%h)
If you're running IM v6 you can use FX expressions with "-set" to set image attributes. By setting the page geometry you can specify the offsets to a calculated percentage and do the crop like this...
convert image.png -set page -%[fx:w*0.1]-%[fx:h*0.1] -crop 50%x+0+0 result.png
That reads the image, sets the geometry for the upper left corner to a location outside the original canvas, and crops to the new top left corner specified by the geometry.
Note the offsets are negative numbers.
Also, if you're doing additional processing in the same command you'll probably want to "+repage" after the crop in order to reset the page geometry to the new WxH+0+0.
Edited to add: You can even include the width and height dimensions for the crop when using "-set page". This command would crop an output of 50% the input width and height, and starting at 10% in from the left and top...
convert image.png \
-set page %[fx:w*0.5]x%[fx:h*0.5]-%[fx:w*0.1]-%[fx:h*0.1] -crop +0+0 result.png
Notice how the crop operation is simply "-crop +0+0" since the dimensions and offsets are in the page geometry.
This method lets you use more complex calculations than just using a percent or number of pixels for the cropped output dimensions.
You cannot do that in ImageMagick 6. But you can do that in ImageMagick 7.
magick image.png -crop "50%x+%[fx:0.1*w]+%[fx:0.1*h]" +repage result.png
In ImageMagick 6, you need to do the computations ahead of the command, store them in a variable and use the variable in the crop command.
However, in ImageMagick 6, you can do the equivalent using -distort with viewport processing as follows:
convert image.png -set option:distort:viewport "%[fx:0.5*w]x%[fx:0.5*h]+%[fx:0.1*w]+%[fx:0.1*h]" -filter point -distort SRT 0 result.png
With v7 ImageMagick, make start image:
magick -size 200x100 gradient: a.jpg
Now crop using lots of calculated widths, heights, offsets:
magick a.jpg -crop "%[fx:w*0.9]x%[fx:h*0.8]+%[fx:w*0.1]+%[fx:h*0.05]" b.png
Check:
identify b.png
b.png PNG 180x80 200x100+20+5 8-bit Gray 256c 408B 0.000u 0:00.000
If you only have v6, use bash and integer arithmetic:
read w h < <(identify -format "%w %h" a.jpg)
convert a.jpg -crop $((w*80/100))x$((h*90/100))+$((w*10/100))+$((h*5/100)) result.png
Check:
identify result.png
result.png PNG 160x90 200x100+20+5 8-bit Gray 256c 412B 0.000u 0:00.000

ImageMagick convert format, crop and resize

I have a large number of research pdf figures, and I need to preform the following actions in ImageMagick:
convert all pdf to png
crop png from left/top corner x:334/y:244; from right/bottom corner x:214/y:340;
original size 2100x2100, cropped size 1552x1552 pixels
resize cropped png to 240x240 pixels
Here is how it should be cropped for point 2, the pink area is what I want to have:
I was only be able to get 1st action done with my knowledge:
mogrify -format png -density 300 -flatten *.pdf
How can I do the 2nd and 3rd actions please? And do I need to run three separated commands or could they be combined into one command?
I do not know what exact order you need for mogrify as I do not use it. I also do not know why you need flatten Try:
mogrify -format png -density 300 -crop 1552x1552+344+244 +repage -resize 240x240 *.pdf

Cropping with ImageMagick always results in 1x1 images

I'm trying to crop an image into a bunch of 256x256 tiles (with the right-most and bottom-most images less than 256 pixels due to the remainders), but ImageMagick always generates images that are 1x1.
I use this command (Windows 7 command prompt):
convert WBS.png -crop 256x256 +repage +adjoin output\WBS_%02d.jpg
After cropping the following message is displayed:
convert: geometry does not contain image `WBS.png' # warning/transform.c/CropImage/589.
After cropping, the output folder contains 1634 jpg files, all of which are 1 x 1 pixel. The source image is 7218x7650.
Suggestions? I'm sure I'm making some blatant mistake, but I don't know what it is.
This can happen if the origin of the image is not at 0,0. In that case, using +repage before processing the image should do the trick, i.e.
convert WBS.png +repage -crop 256x256 +repage +adjoin output\WBS_%02d.jpg
See also the documentation of the -crop option.

Cropping images with ImageMagic produces wrong size images - why?

There is a bunch of images that represent the pages, scanned from a book and already cropped with ImageMagic. They are all uniform, 629x625 pixels. I need to process them further to prepare for creation of a PDF: split them into odd and even pages. They are named canvas-00.png through canvas-53.png
When I use the following command to get the odd pages first, I get completely butchered images 275x563 pixels extracted from a wrong horizontal offset:
convert canvas-??.png -crop 314x625+0+0 ~/Pictures/odd/canvas.png
What am I doing wrong?
PS: Originally the images were larger, contained extra margins with scanner's lid visible, and I successfully cropped them to 629x625 using a very similar command, but of course with non-zero offset of +140+71. So it baffles me that a visibly more trivial command with zero offset does not work at all.
I suspect you have page offsets "remembered" in your PNG files and you need to clear them.
As an example, let's create an image 500x300 pixels:
convert xc:red xc:lime +append \
\( xc:blue xc:magenta +append \) -append -resize 500x300\! start.png
Now let's crop out a piece towards the bottom right corner, which I intentionally made magenta so you can see which piece I got:
convert start.png -crop 200x100+250+150 z.png
But if we now look at it with identify you can see it "remembers" where it was in the original picture:
identify z.png
Output
z.png PNG 200x100 500x300+250+150 16-bit sRGB 51.1KB 0.000u 0:00.000
This will then potentially affect (i.e. mess up) anything you do in future with the image. The solution is to use +repage to reset all the page geometry and layout so it forgets. You can either do this when cropping, or when using the cropped image later - depending whether you want to retain the crop information or not. (Sometimes you do want it when you are doing jigsaw puzzle processing and maybe want to reassemble the pieces later).
convert start.png -crop 200x100+250+150 +repage z.png
identify z.png
z.png PNG 200x100 200x100+0+0 16-bit sRGB 51.1KB 0.000u 0:00.000
In your case, if you already cropped and saved without repaging, you can load your images and repage prior to actual use:
convert canvas-??.png +repage -crop 817x1040+0+0 ~/Pictures/odd/canvas.png

get the most representative colour from the uppermost pixel of a picture (the sky colour)

Using any language readily available under a UNIX system, I'd like to get the the representative RGB colour values for the uppermost pixels of a JPG file.
In other words, given an image file, I'd like to -crop3072x1, resize to 1x1 (obviously without preserving the aspect ratio), then get the RGB value of the resulting pixel.
Using GraphicsMagick, there's apparently a TXT image format that's available:
gm convert IMG_X.JPG -crop x1 -resize 1x1\! txt:-
For example:
% gm convert IMG_7753.JPG -crop 2800x1 -resize 1x1\! txt:-
0,0: ( 63,107,158) #3F6B9E
References:
http://www.graphicsmagick.org/convert.html
http://www.graphicsmagick.org/GraphicsMagick.html#details-crop
http://www.graphicsmagick.org/GraphicsMagick.html#details-resize
http://www.graphicsmagick.org/GraphicsMagick.html#details-geometry

Resources