使用SRT将图像缩放到使用imagemagick时可能的最小比例

问题描述 投票:0回答:1

[这是Crop and resize image around a custom focus point的后续问题,在此我获得了有关用于imagemagick的哪些命令部件以实现我想要的功能的有用答案:缩小图像,而不是使用预定义的引力(例如“ Center “或” North“),我想在图像上使用自定义焦点,该焦点应该是缩放图像的新中心,以确保在裁剪/调整大小时始终可以看到图像的“重要点”。

这非常有效,除了实际尺寸计算。我想我的数学有问题,因为如果图像缩小的幅度超过了我的计算,结果输出将丢失一些可见的部分。我找不到我正在做的错误,也许有人可以向我提示正确的方向。

我目前在做什么:

# Example image from https://unsplash.com/photos/p-I9wV811qk
source_image = 'input.jpg'

source_image_size = [3008, 2000]
target_image_size = [295, 195]

# Focus point position, in percentages.
focus_point = {
  x: 46.7087766,
  y: 24.2
}

# Calculate the focus point in px on the source image.
source_focus_point = [
  source_image_size[0] / 100.0 * focus_point[:x],
  source_image_size[1] / 100.0 * focus_point[:y]
]

# Calculate the distances to the focus point in percentage,
# from all four image sides, and use the smalles value.
smallest_percentage_distance = [
  focus_point[:x],
  (100.0 - focus_point[:x]),
  focus_point[:y],
  (100.0 - focus_point[:y])
].min

# Scale image to reach smallest percentage distance.
scale_factor = smallest_percentage_distance / 100.0

# Calculate the focus point on the target image for the transformation,
# which will be on the center of the new image.
target_focus_point = [
  target_image_size[0].to_f / 2.0,
  target_image_size[1].to_f / 2.0
]

# Define how many degrees the image should be rotated.
rotation_degrees = 0

command = [
  'convert',
  source_image,
  "-set option:distort:viewport #{target_image_size.join('x')}",
  "-distort SRT '#{source_focus_point.join(',')} #{scale_factor} #{rotation_degrees} #{target_focus_point.join(',')}'",
  'output2.jpg'
].join ' '

结果命令是:

convert input.jpg -set option:distort:viewport 295x195 -distort SRT '1405.000000128,484.0 0.242 0 147.5,97.5' output.jpg

据我所知,imagemagick扭曲了SRT的第二个参数(此处为scale_factor),它定义了按比例缩小图像的百分比。我的想法是计算各方到焦点的距离,取最小距离,将其转换为合适的参数,然后使用该参数定义缩放比例。

目标是尽可能缩放图像,以确保输出图像不会裁剪过多,以便尽可能多地显示原始图像。我的输出现在截断太多。

我试图将其可视化以更好地理解:enter image description here

我做错了什么?如何计算正确缩小图像的值,以使尽可能多的图片可见?

编辑1最后,将生成具有不同纵横比的图像的多个变体。在给定的295x195旁边,另一个将为1440x560;特别是在这种情况下,一个简单的“重力重播”很可能会裁剪出图像的中部或上部,因此,确保始终可见关键部分的焦点就可以了。

ruby imagemagick imagemagick-convert
1个回答
0
投票
这是我在Imagemagick(Unix语法)中的处理方式

输入:

enter image description here

# get image dimensions and aspect ratio WxH=`convert barn.jpg -format "%wx%h" info:` ww=`echo "$WxH" | cut -dx -f1` hh=`echo "$WxH" | cut -dx -f2` aspect=`convert xc: -format "%[fx:$ww/$hh]" info:` # define centering point px=200 py=200 # compute distances to each side of the image dleft=$px dright=$((ww-px-1)) dtop=$py dbottom=$((hh-py-1)) # find the minimum distance and to which side dminx=`convert xc: -format "%[fx:round(min($dleft,$dright))]" info:` dminy=`convert xc: -format "%[fx:round(min($dtop,$dbottom))]" info:` dmin=`convert xc: -format "%[fx:round(min($dminx,$dminy))]" info:` # compute crop width, height and scale percent if [ $dmin -eq $dminx ]; then wd=$((2*dminx)) ht=`convert xc: -format "%[fx:round($wd/$aspect)]" info:` scale=`convert xc: -format "%[fx:100*$ww/$wd]" info:` else ht=$((2*dminy)) wd=`convert xc: -format "%[fx:round($ht*$aspect)]" info:` scale=`convert xc: -format "%[fx:100*$hh/$ht]" info:` fi # compute x and y offsets to the top left corner of crop region xoff=`convert xc: -format "%[fx:round($px-$wd/2)]" info:` yoff=`convert xc: -format "%[fx:round($py-$ht/2)]" info:` # crop and resize the image to original dimensions convert barn.jpg -crop ${wd}x${ht}+${xoff}+${yoff} +repage -resize $scale% barn_result.jpg

结果:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.