将图像裁剪为特定比例的算法

5
我需要一个算法,根据图像的宽度、高度和目标比例计算从图像两侧切割的像素数量,并且使得图像面积变化最小
如何实现这样的算法? 编辑 抱歉我的原问题不够一致,我已经修改了它。

“计算需要从图像边缘削减的最小像素数”与“离0最近的shave_width - shave_height”是不同的目标。您想要哪一个? - mbeckish
1
为了阐述@mbeckish的评论,假设给定的示例值为宽度=500,高度=270和比率=2。那么shave_width = shave_height = 40使得shave_width - shave_height == 0。它们是期望的值吗? - tafa
(w-sw)/(h-sh) = r, sh = h + sw/r -w/r, differentiate d(sh)/d(sw) = -1/r, diff is 0 at minimum sh. Which isn't any help! Might I suggest an iterative, trial and improvement binomial approach instead? You give a concise mathematical explanation but I struggle to see the application of such an algorithm.(w-sw)/(h-sh)= r,sh = h + sw / r - w / r,微分d(sh)/ d(sw)= -1 / r,在最小的sh处diff为0。这并没有什么帮助!我建议采用迭代、试验和改进的二项式方法。你给出了一个简明的数学解释,但我很难看出这种算法的应用。 - John
继续@tafa的例子 - 答案是否为shave_width=0,shave_height=20,这满足“计算需要从图像边缘削减的最小像素数”? - mbeckish
1
也许您想要最小化原始图像和最终图像之间面积的变化?Min((xy)-((x-sx)(y-sy))? - mbeckish
是的,谢谢。那是一个更好的解决方案。 - moteutsch
2个回答

6
  1. 将比例带入简化形式,使得gcd(ratio_width, ratio_height) = 1。
  2. 计算floor(width / ratio_width)和floor(height / ratio_height)。您的因子是这两个值中的最小值。
  3. 将ratio_width和ratio_height乘以该因子以获得新图像尺寸。
  4. 刮掉差异部分。

0
为了最小化面积的变化,您想要找到所需宽高比的最大矩形,以适应原始图像边界内。
因此,如果原始图像太宽,则使最终图像的高度=原始高度,并削减额外的宽度。
如果原始图像太高,则使最终图像的宽度=原始宽度,并削减额外的高度。
注意:这假设您不允许将宽度或高度增加超出原始尺寸。如果不是这种情况,算法将是:
约束1:x_final * y_final = x_initial * y_initial
约束2:x_final / y_final = r 解决方案是:
x_final = sqrt(r*x_initial*y_initial)
y_final = sqrt(x_initial*y_initial/r)

1
@harold - 是的。这取决于应用程序。例如,如果给定的比率具有8位数字精度,并且需要数百万像素才能获得精确的比率呢?你想要一个巨大的图像还是足够接近的纵横比? - mbeckish
1
@harold - 这就是我说它是应用程序特定的原因。4x4是一个相当牵强的例子。如果图像大小为400x400,那么400x267可能是可以接受的结果。如果您真的正在使用4x4,其中单个像素的更改会极大地改变纵横比,那么您可能需要尝试其他方法。 - mbeckish
1
@harold - 此外,在您的示例中,谁能说3x2比4x3更正确?存在两个竞争目标:保持面积不变和改变为新的长宽比。4x3将更接近原始面积,但在长宽比上更远。3x2将是正确的长宽比,但在面积上更远。 - mbeckish
1
@harold - 这是另一个例子。假设原始图像的尺寸为400x400,期望的宽高比为201:170。按照你的观点,最终图像应该是201x170。按照我的观点,最终图像应该是400x338。问题中提供的细节不足以确定对他的特定应用来说哪种方式更好。 - mbeckish
1
@harold - 这似乎不会给你一个非常合理的宽高比近似值,是吧? ;) - mbeckish
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接