3

我的目标是从给定数量的尺寸中选择最合适的图像尺寸。

给定一些相当随机的分辨率,我想找到一个尺寸尽可能接近我首选尺寸的图像。

假设我想使用尺寸为宽 x 高 ( preferredImageSize) 的图像。

示例:320x200

假设我可以使用以下图像尺寸 ( availableImageSize) width1 x height1, width2 x height2, ...(可能多达 10 种不同的尺寸)。

示例:474x272、474x310、264x150、226x128、640x365、474x410、480x276、256x144、160x90、320x182、640x365、192x108、240x137、480x276

为了开发一些通用的方法来制作preferredImageSize变量,我试图找到一个很好的解决方案,它计算得相当快,但也会产生在屏幕上看起来不错的东西。

我将在屏幕上看起来不错的图像定义为:

  1. 几乎没有升级
  2. 尽可能接近给定的纵横比 ( preferredImageSize.width / preferredImageSize.height)
  3. 可能会大幅缩减
  4. 可能会被裁剪/拉伸非常少量

我最初的(相当微不足道的)方法:

遍历可用的图像尺寸一次并找到最小的宽度增量 ( abs(preferredImageSize.width - availableImageSize.width))。然后选择具有最小增量的图像 ( bestFitWidth)。

那当然是解决问题的一种方法,但绝对不符合我在屏幕上看起来不错的希望。

任何提示,无论是文本、来源还是链接都会很棒。哦,如果您认为我的要求(又名希望)已经导致错误的方向,请继续,让我知道...


编辑:添加裁剪和拉伸作为选项 - 恐怕这会使问题更难解决。因此,如果需要,请将其排除在等式之外。

4

1 回答 1

3

简单的“如果/那么”方法:

我会做两件事:

  1. 由于您宁愿不放大,但可以缩小尺寸(我发现这是一个不错的选择),因此切勿使用小于目标的源图像,除非没有可用的图像。
  2. 由于“大量”缩小是可以的,我会尝试找到一个尽可能匹配纵横比的图像,从可接受的最小图像开始,然后逐渐变大。

把它放在一起,首先从列表中丢弃所有小于目标的图像。然后,从剩下的最小图像开始,检查其与目标的纵横比。如果不匹配是可以接受的(您需要量化),请使用图像,否则转到下一个更大的图像。如果您没有找到任何可接受的,请使用最匹配的那个。

如果您已经丢弃了所有小于目标的图像,那么无论哪种方式,您最终都可能会得到一个看起来很糟糕的图像,但是您应该尝试使用需要更多放大的图像是否更糟,或者是否使用更糟糕的纵横比匹配的图像更糟糕。

您需要考虑的另一件事是您是否要拉伸或裁剪图像以匹配您的目标纵横比。

更复杂的定量方法:

不过,最灵活的方法是为自己定义一个“惩罚”函数,该函数取决于大小不匹配和纵横比不匹配,然后找到给您最低“惩罚”的源图像。这是您当前所做的,并且您已将惩罚函数定义为abs(preferredImageSize.width - availableImageSize.width). 您可以使用更复杂的东西,例如:

width_diff  = preferredImageSize.width  - availableImageSize.width
height_diff = preferredImageSize.height - availableImageSize.height
if (width_diff > 0) width_penalty = upscale_penalty   * width_diff
               else width_penalty = downscale_penalty * width_diff
if (height_diff > 0) height_penalty = upscale_penalty   * height_diff
                else height_penalty = downscale_penalty * height_diff
aspect_penalty = ((preferredImageSize.width / preferredImageSize.height) - 
                  (availableImageSize.width / availableImageSize.height)) * stretch_penalty;
total_penalty = width_penalty + height_penalty + aspect_penalty;

现在您可以使用 3 个数字upscale_penalty, downscale_penalty, 并stretch_penalty赋予这三个降低质量的操作不同的重要性。只需尝试几种组合,看看哪种效果最好。

于 2013-03-05T23:13:46.263 回答