Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.
I need to add borders on top/bottom or right/left of some images so that they can be displayed fullscreen on 4x3 and 16x9 format tv screens. The 4x3 screen images should be720px × 540px, and 16x9 images should be 720px × 576px, Is there an easy way of doing this using mogrify?
Something like this works for creating the 4x3 version of my test image:
gm mogrify -size 720x540 -gravity center -resize 720x540 -mattecolor black -frame '0x0<' -crop 720x540+10+0 -quality 90 test.jpg
but I don't quite understand the crop option, and I think the y-offset (10) is specific for this image. An image with different porpotions will likely yield different x and y offsets. Is there any way of cropping the image to 720x540 keeping the porpotions and adding a border/background color for where the original image woun't cover ?
I first add a frame that I know is too big, then crop it to fit the screen.
gm mogrify -size 720x540 -resize 720x540 \
-bordercolor black -frame 360x270 \
-gravity center -crop 720x540+0+0 \
-quality 90 test.jpg
The cropping offsets are 0 because
cropped region has already been centered
by the gravity.
This works, thanks!
But could you please explain what "-frame 360x270" does here ? It looks smaller than 720x540.. or is it a frame of 360x270 surounding the image, meaning it will minimum occupy 2x 360 in X-direction, and 2x 270 in Y-direction = minimum size of 720x540. hmm, that was too perfect - guess I understand it after all :-)
"-frame 360x270" adds 360 columns on left and right, and 270 rows on top and bottom. The resulting picture is guaranteed to be at least 720x540, even if it starts out as 1x1 (pathological case). More typically your image won't need nearly that many extra rows and columns, and it's somewhat wasteful of memory. But it's guaranteed to work!
If you're putting this into a workflow that you will be using a lot, there are more efficient ways. Another good one is to create a 720x540 (or x576) blank black image and then compose your resized image over it with "-gravity center".
Yes, this is going into a workflow that will be used a lot, so if the overlay version is better, we should be using it… Could you please help me with the syntax here as well? (I'm quite new to GM, and the manual is a bit hard to follow unfortunately)
gm composite -size 720x576 -resize 720x576 input.jpg \
xc:black -gravity center -quality 92 out_576.jpg
gm composite -size 720x540 -resize 720x540 input.jpg \
xc:black -gravity center -quality 92 out_540.jpg
Caution: the syntax for composite is different for ImageMagick.
Incidentally, 16x9 isn't 720x576 (see http://en.wikipedia.org/wiki/List_of_common_resolutions). I think you really want 960x540:
gm composite -size 960x540 -resize 960x540 input.jpg \
xc:black -gravity center -quality 92 out_960x540.jpg
In GraphicsMagick 1.3.11 and later there is an -extent command option which does exactly what you want:
gm mogrify -background black -gravity center -compose Copy -extent 720x576 *.jpg
Look for documentation on -extent. If you use -resize, then make sure that it occurs on the command line prior to -extent.
Right, you'd need to "-resize" as in my method using composite
Otherwilse you'll just crop out a little piece of the middle of the input
You should continue to use "-size" also if the input is a JPEG because
it speeds up the resizing. And yes, use "-compose Copy" in either
case because it's probably faster than the default "Over" composition.
Based on this discussion, I checked in this example to the "options" documentation for "-extent":
This command reduces or expands a JPEG image to fit exactly on an 800x600 display. If the
aspect ratio of the input image isn't 8x6, then the image is centered within an 800x600 black canvas:
gm convert -size 800x600 input.jpg -resize 800x600 -background black \
-compose Copy -gravity center -extent 800x600 -quality 92 output.jpg
glennrp: your link to the wikipedia list of common resolutions list 720x576 as DVD(PAL) . The use here is a STB portal running slideshows in 4:3 (720x540) or 16:9 (720x576) SD resolution. I have no idea about how we've come up with these sizes, but that's what I believe we've been using so far - so I assume it works as it should.
We're stuck with the GraphicsMagick version provided by EPEL (1.3.7), so I guess we will have to stick with the "gm composit" version for now. Many thanks for helping me with the syntax here ! Hope I'll get the hang of the syntax eventually :-)
It seems my formats were a bit wrong. For the 4/3 display we need to keep the aspect ration, so we scale down the overlay image to 720x540 on top of a 720x576 canvas:
gm composite -size 720x576 -resize 720x540 input.jpg xc:black -gravity center -quality 92 output.jpg
while for 16/9 we need to make the image anamorphic. I´m not 100% sure this is correct, but it seems to be working:
gm composite -size 720x576 -resize '70.3125%x100%>' -resize 720x576 input.jpg xc:black -gravity center -quality 92 output.jpg
What I *think* this is doing is to squeeze the image down to 70.3125% in horizontal direction (keeping vertical at 100%), then scale it down to maximum 720x576 on a black canvas.
Any comments on this? Am I doing things strangely… ?
And is 70.3125% the magic anamorphic widescreen constant ? The way I arrived at this was that I was told one could create an anamorphic widescreen image by scaling the image to 1024xY (keeping aspect ratio), and then squeeze it to 720 horizontally without changing the vertical size (1024*70.3125% = 720).
If your display system is always expecting anamorphic images (wide pixels) then you should use a "!" instead of ">" so that even if your input is smaller than 720x576 in either or both dimensions its width will be compressed before the final overlay on the 720x576 canvas. Test with an input that is 1000x577 versus one that is 1000x575. They should look quite similar but I think your method will produce one that is quite stretched compared to the other.
Do you have a way of passing information to the display about whether the image has square pixels or nonsquare (anamorphic) ones? I know you could do it with the PNG pHYs chunk (if the display systems understands the pHYs chunk) but I don't know about JPEG. If you don't know about that then the safest thing is to use "!" in the resize geometry string.
OK, thanks for tip about "!", will implement that.
The images here are pre-generated, and the TV portal will know to pick the 16/9 or 4/3 versions based on the output settings in the STB. I believe we´ll always be using anamorphic for 16/9 displays.
Each resize loses a bit of quality and takes time so if you can reduce to just one -resize request you will get more speed and more quality.
The first option should be "-size 1024x576" when you are making 16:9 because you are going to squeeze the image after decoding the JPEG, and then you need another "-size 720x576" to specify the dimensions of the canvas.
gm composite -size 1024x576 -resize '70.3125%x100%!' -resize 720x576 input.jpg -size 720x576 xc:black -gravity center -quality 92 output.jpg
If you are making a 4:3 image, then "-size 720x540" is correct.
I don't see a simple way of combining the two -resize operations without knowing the actual dimensions and aspect ratio of the input. Anyway, both are happening after the "-size" operation has already reduced the image to nearly the right size, so they should be relatively inexpensive.
When the target is 4:3, then only a single "-resize" is needed, as in the first "composite" command in comment #12.
So for 4:3 the correct command should be:
gm composite -size 720x540 -resize 720x540 input.jpg -size 720x576 xc:black -gravity center -quality 92 output.jpg
I had some scripts doing the conversions with an environment variable NCPUS=6 (indicating I planned on running 6 simutanous processings), but it seems GM was interpreting this as OMP_NUM_THREADS and we ended up running 6x6=36 threads on each of our 8 core server.. This was quite slow, but once we definded OMP_NUM_THREADS=2 and NCPUS=4 we got fantastic performance. Initial testing seemed to inidicated 0.10 second per image when running on two servers with two quad core cpus each.