I'm trying to create thumbs of an equal size, and I want no padding whatsoever. The thumb should be 154x208 pixels. The original can vary in shape and size.
I'm using ImageMagick, first I tried this:
convert org.jpg -thumbnail 154x208 dest.jpg
This will create a thumbnail that is maximum 154 pix wide AND maximum 208 pix of height. I want an image that is 154x208 pixels though. Without padding.
I tried this:
convert org.jpg -thumbnail x208 -crop 154x208+0+0 dest.jpg
This works great on an image in landscape mode, but a picture in portrait mode results in a thumb that's too narrow. -extent instead of -crop gives me the right end-result, but that ads padding to the thumbnail, and I don't want that.
I'm looking for a thumbnail from a picture that either has the full height and crops the width to fit, or the full width and crops the height, always resulting in a 154x208 thumbnail with no padding, using ImageMagick
I solved it by treating images with a smaller width-to-height ratio different from ones with a larger one:
a smaller width-to-height ratio than 154x200 image:
convert org.jpg -thumbnail 154 -gravity center -crop 154x200+0+0 dest.jpg
and a higher ratio:
convert org.jpg -thumbnail x208 -gravity center -crop 154x200+0+0 dest.jpg
It is an extra step in my coding, and I am still interested in an answer that doesn't need this extra step, but it does the job for now!
Related
First, the goal of this task is to get images to be visually as large as possible by removing excess around the the edges.
I have tried fuzz and -gravity center and they both do a good job although I think I prefer gravity.
There is a small issue though, and that is the cropping leads to images that are not retaining aspect ratio and therefore are visually non conformant to the place where they are to be displayed.
I will demonstrate using images:
I start with this input image (800x800), pay attention to edges:
When I apply the command magick "${file}" -gravity center -trim "${out}"
I get the following output (696x656), where you can see whitespace at the top and bottom edge. This is kind of ok here, however, the image sits next to another image and the difference in height is quite annoying to see. This might be ok, here but there are worse examples.
Instead, aspect ratio should be kept, and in this case, the previous image should retain the parts that are white around the edges.
A quite complex attempt to solve this was to recalculate the height to 696 which does work to get extra pixels but they are however white pixels and not the underlying images pixels:
magick "${file}" -gravity center -trim -extent "696x696" "${out}"
This white edges are now in fact part of the image where the first ones are not so aspect ratio is kept but in a rather clunky way.
So the only problem is how to tell gravity center to retain those parts.
Ideally though, any gravity operation should be performed using an aspect ratio in mind and the gravity operation should find the best scaled aspect ratioed square to use for cropping.
On another note, what is the info return values widthxheight+something+something? What are the somethings?
So I think I've got it:
magick "${file}" -gravity center -trim -extent "800x800" "${out}"
Will give me
and
magick "${file}" -gravity center -trim -extent "800:800" "${out}"
Will give me:
So the x is to be switched for a :
Note that:
magick "${file}" -gravity center -trim -extent "696x696" "${out}"
will give
and so rather than put back the height ImageMagick goes a step further and tries to crop more from the width which is actually the desirable, albeit a bit of the snails tail seems to be cut in picture two.
There should be an option I guess for how aggressive it is to walk between expanding height vs eating width.
But I am quite satisfied. Thanks #fm42!
EDIT
This is not always ideal, that it goes for the width rather than fill the whitespace:
This:
now leads to:
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.
I am trying to crop an image starting from top-right and cut out a 48x48 box.
This is the image I'm working with
I've tried this
in.png -gravity northeast -crop 48x48 out.png
out-0.png
out-1.png
out-2.png
out-3.png
Which creates like 4 files, none of which are what I want.
When I add x and y values (which I don't want to), it crops from the northeast correctly with only 1 output image, but the box is not 48x48, its 46x38
in.png -gravity northeast -crop 48x48+0+0 out.png
out.png
This gives different outputs for different images. I just tried another and ended up with a 33x48 output.
I need to use the gravity setting instead of the x and y offsets because I'm batch processing a lot of images that are different sizes.
This is the desired output
Can someone please explain to me what I'm doing wrong? Thanks!
If your input image has paging information, the result of your crop may not be what you expect. When working with unknown images, you might do a "+repage" right after reading in the image. Also, when you "-trim" an image, the paging information from the original image remains. The "-crop" will use that paging information instead of the actual height and width, so "+repage" after a "-trim" unless you know you'll need that information. Try this...
convert inimage.png -trim +repage -gravity northeast -crop 48x48+0+0 outimage.png
You should also use "+repage" after any crops if you intend to continue processing the images.
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.
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.