Page 1 of 1
geometry calculations
Posted: 2012-07-28T13:25:29-07:00
by Draoidh
I am creating the following image by appending two canvases:
In real life, the geometry of the canvases is derived from two existing image files.
Code: Select all
convert -bordercolor black \( -size 200x100 "xc:#080" \) \( -size 200x30 "xc:#800" -gravity South -extent x200% \) -append -border 5% fg.png
Now I would like to create the following image based on the same geometry information:
As I really don't know how to express this with ImageMagick, I'll describe it in plain English:
The image below has the same dimensions as the one created above. The green block extends down to the MIDDLE of the white gap.
I am at my wits end. If anyone can give me an idea how to calculate these two areas, I'd be very grateful
Re: geometry calculations
Posted: 2012-07-28T14:17:57-07:00
by fmw42
You have made things very hard by using mixed pixels and percents and by using -gravity south to pad the middle with white in your first image. It would have been better to have spoecified 3 sections to append: green, white, red
Your output image will be 200*1.10=220 wide (the 1.10 comes from 5% additional on each side).
It will also be (100+60)*1.10=176 (though your output is actually 180?). The 60 comes from 200% x 30 for the second part. So adding in the first part of 100 and padding by 5% on both sides gives 176.
Since the green is 100 pixels tall, the white is 30 pixels and red is 30 pixels. Half way down to the middle of the white would be 115 pixels before padding. So the remainder before padding will be 160-45=115. With the padding it will be 45+180*.05=54
Thus the easiest way is to do:
convert \( -size 220x180 xc:"green1" \) \( -size 220x54 xc:"red" \) -gravity south -compose over -composite 1result.png
Re: geometry calculations
Posted: 2012-07-28T17:48:45-07:00
by Draoidh
Many thanks for your reply.
The code I posted is a simplified snippet from a parameter driven shell script. The geometry info is in shell variables, derived from varying input pictures:
Code: Select all
DIM1=$(identify -format %wx%h $PIC1)
DIM2=$(identify -format %wx%h $PIC2)
convert ... \( -size$DIM1 "xc:#080" \) \( -size$DIM2 ...
PIC1 and PIC2 have the same width.
Your solution was to create a full-size green box and overlap it with the smaller red one. I would prefer not to do that because the green box might be a gradient rather than a solid colour in which case I'd need to specify the exact height of both the green and the red box.
Like you, I had worked out the figures for this example to produce the second image. However, my problem is whether this can be done programmatically.
Re: geometry calculations
Posted: 2012-07-28T17:57:00-07:00
by fmw42
If you can compute the parameters as I did above, then you should be able to program it.
This works for me
width=200
height1=100
height2=30
border=5 #percent
ww=$(convert xc: -format "%[fx:$width*(1+2*$border/100)]" info:)
pad=$(convert xc: -format "%[fx:($height1+2*$height2)*($border/100)]" info:)
hh1=$(convert xc: -format "%[fx:$height1+($height2/2)+$pad)]" info:)
hh2=$(convert xc: -format "%[fx:(3/2)*$height2+$pad]" info:)
echo "ww=$ww; pad=$pad; hh1=$hh1; hh2=$hh2;"
convert \( -size ${ww}x${hh1} xc:"green1" \) \( -size ${ww}x${hh2} xc:"red" \) -append 1result.png
But the result is 176 high and not 180. The problem is that -border 5% is not working correctly.
The base image height before the border is 100+2*30=160.
Adding the padding of 5% should give 160*(1+2*.05)=160*1.1=176
When I do the following:
convert -size 200x160 xc:white -bordercolor black -border 5% -format "%h" info:
180
Thus -border specified as 5% is not computing correctly. It seems to be using something like 6.25% as 160*1.125=180
Seems like a bug to me. I have reported it at
viewtopic.php?f=3&t=21537
Re: geometry calculations
Posted: 2012-07-28T19:40:01-07:00
by fmw42
I got a reply back from Magick. Seems that IM will compute the pixels from the percent value. If only one percent value is supplied, then the pixel value will be used for both dimensions. That means if the image is not square and you specify 5%, that will convert to 5% * width to compute the pad in pixels and use it for both the padding in the width and height. If you really want 5% for both width and height, you need to specify -border 5%x5% or -border 5x5%. This is what I had computed above (thinking incorrectly that the 5% would apply to both dimensions).
Thus if you want to continue to use -border 5%, then my computations above should be modified to:
width=200
height1=100
height2=30
border=5 #percent
pad=$(convert xc: -format "%[fx:($width)*($border/100)]" info:)
ww=$(convert xc: -format "%[fx:$width+2*$pad)]" info:)
hh1=$(convert xc: -format "%[fx:$height1+($height2/2)+$pad)]" info:)
hh2=$(convert xc: -format "%[fx:(3/2)*$height2+$pad]" info:)
echo "ww=$ww; pad=$pad; hh1=$hh1; hh2=$hh2;"
convert \( -size ${ww}x${hh1} xc:"green1" \) \( -size ${ww}x${hh2} xc:"red" \) -append result.png
Re: geometry calculations
Posted: 2012-07-29T05:12:04-07:00
by Draoidh
Fred, thanks so much for working through this example for me. I thought fx could do the job but had a few missing links such as info:.
Re: geometry calculations
Posted: 2012-07-29T07:00:38-07:00
by Draoidh
Before I gave up and posted my question, I had tried to do the calculations inline:
Code: Select all
convert \( -size 200x100 xc:"green1" \) -extent "%[fx:w*2]" x.png
Re: geometry calculations
Posted: 2012-07-29T11:24:50-07:00
by fmw42
Draoidh wrote:Before I gave up and posted my question, I had tried to do the calculations inline:
Code: Select all
convert \( -size 200x100 xc:"green1" \) -extent "%[fx:w*2]" x.png
IM 6 does not allow that in most cases, only a few commands such as -distort, -sparse-color ... allow such. But IM 7 will have much more ability to do that sort of thing. It was one of the major issue that are being worked on by Anthony at this time. You can try IM 7 if you want to experiment, but it is only in alpha development.
Re: geometry calculations
Posted: 2012-07-29T11:40:38-07:00
by Draoidh
After all this, I have realized that I can achieve my objective in a much simpler way, which is not to say that I am not interested in the fx stuff at some point.
Making use of the fact that -border <width> gives me an equal-sized border, I create the gap with -border rather than -extent:
Code: Select all
convert -bordercolor black \( -size 200x100 "xc:#080" \) \( -size 200x30 "xc:#800" \) -border 5% -append fg.png
The gap has a slightly different height but still looks good in my context.
For the second file, it's then going to be easier to split the gap in the middle.
I only take updates from the latest Debian release. It's not always healthy to be at the bleeding edge.
Re: geometry calculations
Posted: 2012-07-29T13:36:53-07:00
by fmw42
You can always add a white gap by just including a middle section of xc:white of the desired size. That is much more direct that trying to use gravity and -extent or anything else. And you can always use -border in pixels to have the same amount all around. Just compute the border from from the sizes of the images that you put together, if you want percent in width or height. This is the first time I have ever seen or tried using -border in %.
Re: geometry calculations
Posted: 2012-07-29T13:55:35-07:00
by Draoidh
fmw42 wrote: This is the first time I have ever seen or tried using -border in %.
That's amazing considering the wealth of scripts you are providing on your site. That's a fantastic piece of work, by the way. I appreciate the amount of work that went into the documentation and examples alone.
Re: geometry calculations
Posted: 2012-07-29T14:14:40-07:00
by fmw42
There is so much to IM, that even I still learn new things often.