如何计算上覆图像的旋转角度,以便它只是对角地嵌入底层图像?

时间:2018-01-23 10:16:58

标签: image math rotation imagemagick watermark

我想在一些照片上对角放置一个水印。这些图片的宽度和长度各不相同,有些甚至可能比水印本身小。

这将在脚本中使用,其中用户可以从不同的选项中选择,例如“水平”,“垂直”,“对角线”或者由他/她自己指定角度。因此我需要计算旋转角度 角度

  • 旋转水印,使其对角放置在下面的图像上。
  • 以恒定比例达到最大可能尺寸。

它看起来像this。 (我也画了对角线。)
正如您所看到的,叠加的图片恰好适合底层图片。如果我选择另一个角度,叠加的图像会变小。

我已经计算了底层图像的对角线,然后计算了相应的角度。问题是长度不一定最大化,如here所示。

我在Ubuntu Linux上使用ImageMagick 6.8.9-9 Q16 x86_64。

这是没有计算的bash代码(正如我所说,它不能很好地工作)。请注意,代码实际上是通过Python3执行的。我发现shell命令在bash中更容易阅读。

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

我非常确定这个问题已经在stackoverflow上解决了,但到现在为止找不到任何东西。

最好的问候 AFoeee

2 个答案:

答案 0 :(得分:1)

我们的基本矩形宽度为W,高度为H,比例为K=H/W,旋转的矩形宽度和高度未知但固定比率为k=h/w

我在照片上标记了相似的角度f。我们可以看到

 H = h * cos(f) + w * sin(f)
 W = h * sin(f) + w * cos(f)
 or
 K * W = k * w * cos(f) + w * sin(f)
 W = k * w * sin(f) + w * cos(f)
 divide the first by the second
 K = (k * cos(f) + sin(f)) / (k * sin(f) + cos(f))
 divide denominator and nominator by cos(f)
 K = (k + tg(f)) / (k * tg(f) + 1)
 K * (k * tg(f) + 1) = k + tg(f)
 K * k * tg(f) + K = k + tg(f)
 tg(f) * (1 - K * k) = K - k

,结果是

 tg(f)  = (K - k) / (1 - K * k)
 f = atan((K - k) / (1 - K * k))

快速检查:对于方格K=1和任何k<1 tg(f)=1,所以f = Pi/4(45度)

请注意,并非所有K和k的组合都有意义

enter image description here

答案 1 :(得分:1)

此ImageMagick命令应采用任何输入图像$ pic和任何叠加图像$ wmark,将叠加旋转到$ angle,调整其大小以使输入图像适合其最大可能尺寸,然后合成以输入图像为中心的叠加

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

读取输入图像并设置密度和背景颜色。然后在括号内读取叠加图像并将其旋转角度。

之后是两个“+扭曲”操作。两者都保持主输入图像按原样并有条件地缩放叠加图像。如果叠加大于输入图像,则第一个“+扭曲”会缩小叠加。如果叠加小于主输入,则第二个放大叠加。在任何一种情况下,叠加都会缩放到适合主输入图像的最大尺寸。

当然,在运行命令之前,您必须设置$ pic,$ wmark和$ angle变量的值。此外,如果您需要对输入图像执行任何操作(如修剪或调整大小),请在命令中但在读取叠加图像之前执行此操作。

请注意,使用“+ distort”会为每个边添加一个像素,因此在每次操作后使用“-shave 1x1”删除这些像素。