近似拟合图像大小

时间:2013-03-05 22:55:43

标签: java c image algorithm pseudocode

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

考虑到一些相当随机的分辨率,我想找到一个尽可能接近我喜欢的尺寸的图像。

假设我想使用图像大小的宽度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变量,我试图找到一个很好的解决方案,计算得相当快,但也会产生一些在屏幕上看起来很好的东西。< / p>

我将在屏幕上看起来很好作为图像:

  1. 几乎没有升级
  2. 尽可能接近给定的宽高比(preferredImageSize.width / preferredImageSize.height
  3. 可能会严重缩小尺寸
  4. 可以非常少量地裁剪/拉伸
  5. 我最初的(相当简单的)方法:

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

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

    任何提示,无论文本,来源或链接是否真棒。噢,如果你认为我的要求(也就是希望)已经导致错误的方向,请继续,让我知道......


    编辑:增加裁剪和拉伸作为选项 - 我担心这将使问题更难解决。因此,如果需要,请将其排除在外。

1 个答案:

答案 0 :(得分:3)

简单的“if / then”方法:

我会做两件事:

  1. 由于你不想升级,但可以降尺度(我觉得这是一个不错的选择),不要使用小于目标的源图像,除非没有可用的。
  2. 由于“沉重”缩小是可以的,我会尝试尽可能接近地找到与纵横比匹配的图像,从最小的可接受图像开始,然后逐渐变大图像。
  3. 要将它放在一起,首先要从列表中丢弃小于目标的所有图像。然后,从剩下的最小图像开始,检查其与目标的纵横比。如果不匹配是可接受的(您需要量化),请使用图像,否则转到下一个更大的图像。如果找不到任何可接受的,请使用匹配最佳的那个。

    如果您已经将所有图像丢弃为小于目标的图像,则无论哪种方式都可能会出现图像质量较差的图像,但是您应该尝试使用需要更多放大图像的图像是否更糟糕,或者使用幅度比较差的图像是否更糟。

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

    更复杂的定量方法:

    但是,最灵活的方法是定义自己的“惩罚”函数,该函数取决于大小不匹配和宽高比不匹配,然后找到给出最低“惩罚”的源图像。这是您目前所做的,并且您已将惩罚函数定义为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_penaltydownscale_penaltystretch_penalty来对这三个质量降低操作赋予不同的重要性。只需尝试几种组合,看看哪种方法效果最佳。