Page 1 of 1

How to calculate the rotation angle for an overlying image, so that it just fits diagonally iniside an underlying image?

Posted: 2018-01-23T02:55:29-07:00
by AVoeee
Hello,
I'd like to place a watermark diagonally over a number of pictures. The width and length of these pictures differ and some might even be smaller than the watermark itself.

This will be used inside a script, in which the user can choose from different options like "horizontal", "vertical", "diagonal" or specify an angle by himself/herself. Therefore I need to calculate the rotation angle.
The angle should
  • rotate the watermark, so that it is diagonally positioned over the underlying image.
  • achieve the maximal possible size at constant proportions.
It would look something like this. (I have also drawn the diagonal.)
As you can see, the overlying picture just fits inside the underlying picture. If i'd choose an other angle, the overlying image would become smaller.

I had already calculated the diagonal of the underlying image and then the corresponding angle. The problem is that the length is not necessarily maximized, as seen here.

I'm using ImageMagick 6.8.9-9 Q16 x86_64 on Ubuntu Linux.

Here is the bash code without the calculation (as i said, it didn't work well). Please note that the code is actually executed via Python3. I find that shell commands are easier to read in bash.

Code: Select all

for pic in *
do
	# if there transparency around the picture, remove it and get the dimensions
	size_ui=`convert -density 300 "$pic" -page a4 -bordercolor none -border 1x1 -trim +repage jpg:- | identify -format "%wx%h" -`

    	# get dimensions of the watermark (in case it changes over time)
    	size_wm=`identify -format "%wx%h" "wm.png"`

    	degree=`CALCULATE_THE_PERFECT_ANGLE`

    	# center the watermark, rotate it and resize it to the same size as the underlying picture
    	convert -density 300 "$pic" -page a4 \( "wm.png" -background none -gravity center -rotate "$degree" -resize "$size_ui" \) -compose over -composite "${pic%%.*}.jpg"
done
I am very sure that this problem has already been solved somewhere in the forum, but could not find anything up to now.

Best regards
AVoeee

Re: How to calculate the rotation angle for an overlying image, so that it just fits diagonally iniside an underlying im

Posted: 2018-01-23T12:54:49-07:00
by GeeMack
AVoeee wrote: 2018-01-23T02:55:29-07:00I am very sure that this problem has already been solved somewhere in the forum, but could not find anything up to now.
This question was answered near the end of this thread. A single ImageMagick command will do it. See my response in that other thread or to your question at StackOverflow for a more complete explanation of how it works. And please give me an upvote over at StackOverflow. Thanks.

Here's the command...

Code: Select all

convert $pic -density 300 -background none \( $wmark -rotate $angle \) \
  +distort SRT "%[fx:(u.w<v.w&&u.h<v.h)&&t?min(min(u.w/v.w,v.w/u.w),min(u.h/v.h,v.h/u.h)):1] 0" -shave 1x1 \
  +distort SRT "%[fx:(u.w>v.w||u.h>v.h)&&t?min(max(u.w/v.w,v.w/u.w),max(u.h/v.h,v.h/u.h)):1] 0" -shave 1x1 \
     -gravity center -compose over -composite $result

Re: How to calculate the rotation angle for an overlying image, so that it just fits diagonally iniside an underlying im

Posted: 2018-01-23T18:31:30-07:00
by GeeMack
AVoeee wrote: 2018-01-23T02:55:29-07:00I had already calculated the diagonal of the underlying image and then the corresponding angle. The problem is that the length is not necessarily maximized, as seen here.
If the angle of the overlay will be variable, the only way you can be sure to maximize it to both width and height is to change its aspect ratio. The black bar in your linked example is roughly 1250x110. If it has to be at that angle and fit both width and height of the base image, you'd have to re-proportion the overlay to around 1250x180. That sort of thing could be done, but it would be more complicated than just making the overlay fit at any angle as large as possible without extending outside the bounds of the input image.

Re: How to calculate the rotation angle for an overlying image, so that it just fits diagonally iniside an underlying im

Posted: 2018-01-24T03:09:16-07:00
by AVoeee
Hello,
@GeeMack: I'm sorry, I've overlooked that you had revised your post. Thanks for the answer!

The angle i was looking for can apparently be calculated by:

Code: Select all

ratio1 = pic1_width / pic1_height
ratio2 = pic2_width / pic2_height
angle = atan ((ratio1 - ratio2) / (1 - ratio1 * ratio2))
A complete explanation can be found here.

I like the way your solution unites everything in one command, do you think it's expandable by the above calculation?

I've tried the following, but have trouble with fx ...

Code: Select all

convert $pic -density 300 -background none \( $wmark \
		-rotate "%[fx:atan(((u.w/u.h)-(v.w/v.h))/(1-(u.w/u.h)*(v.w/v.h)))]" \) \
  +distort SRT "%[fx:(u.w<v.w&&u.h<v.h)&&t?min(min(u.w/v.w,v.w/u.w),min(u.h/v.h,v.h/u.h)):1] 0" -shave 1x1 \
  +distort SRT "%[fx:(u.w>v.w||u.h>v.h)&&t?min(max(u.w/v.w,v.w/u.w),max(u.h/v.h,v.h/u.h)):1] 0" -shave 1x1 \
     -gravity center -compose over -composite $result
As you might see, I tried to calculate the angle, but it doesn't seem to work.

Could it be that your solution only works if the image is landscape format? On some portrait format test images, the watermark was scaled too large.

Please note that I've upvoted your post on StackOverflow, but since I do not have 15 reputations yet, it is not be publicly displayed.

Best regards
AVoeee

Re: How to calculate the rotation angle for an overlying image, so that it just fits diagonally iniside an underlying im

Posted: 2018-02-04T14:03:11-07:00
by AVoeee
Hello,
the end result can be seen in this thread.

Best regards
AVoeee