Java 近似拟合图像大小

Java 近似拟合图像大小,java,c,image,algorithm,pseudocode,Java,C,Image,Algorithm,Pseudocode,我的目标解决方案是从给定的大小中选择最合适的图像大小 考虑到许多随机分辨率,我希望找到一张尺寸尽可能接近我首选尺寸的图像 假设我想使用图像大小的宽度x高度(preferredImageSize) 示例:320x200 假设我可以使用以下图像大小(availableImageSize)宽度1 x高度1,宽度2 x高度2。。。(可能多达10种不同尺寸) 示例:474x272、474x310、264x150、226x128、640x365、474x410、480x276、256x144、160x90、

我的目标解决方案是从给定的大小中选择最合适的图像大小

考虑到许多随机分辨率,我希望找到一张尺寸尽可能接近我首选尺寸的图像

假设我想使用图像大小的宽度x高度(
preferredImageSize

示例:320x200

假设我可以使用以下图像大小(
availableImageSize
)宽度1 x高度1,宽度2 x高度2。。。(可能多达10种不同尺寸)

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

为了开发一些通用方法来生成
preferredImageSize
变量,我试图找到一个好的解决方案,该解决方案计算速度相当快,但结果在屏幕上看起来确实不错

我将屏幕上的外观定义为图像,即:

  • 几乎没有扩大规模
  • 尽可能接近给定的纵横比(
    preferredImageSize.width/preferredImageSize.height
  • 可能会大幅缩减规模
  • 可能会被裁剪/拉伸到非常小的数量
  • 我最初的(相当琐碎的)方法:

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

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

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


    编辑:增加了裁剪和拉伸选项,我担心这会使问题更加难以解决。因此,如果需要,将其从等式中排除

    简单的“如果/然后”方法:

    我会做两件事:

  • 由于您不希望放大,但可以缩小尺寸(我发现这是一个不错的选择),因此永远不要使用小于目标的源图像,除非没有可用的源图像
  • 由于“重”缩小尺寸是可以的,我会尝试找到一个尽可能与纵横比匹配的图像,从最小的可接受图像开始,逐步放大图像
  • 要把它放在一起,首先从列表中扔掉所有比目标小的图像。然后,从左边最小的图像开始,检查它与目标的纵横比。如果不匹配是可以接受的(您需要量化),请使用图像,否则请转到下一个较大的图像。如果你找不到任何可以接受的,就用最匹配的

    如果您已经扔掉了所有比目标小的图像,那么无论哪种方式,最终都可能会得到外观不好的图像,但是您应该尝试使用需要更大比例的图像是否更差,或者使用宽高比匹配更差的图像是否更差

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

    更复杂的定量方法:

    不过,最灵活的方法是定义一个“惩罚”函数,该函数取决于大小不匹配和纵横比不匹配,然后找到“惩罚”最低的源图像。这就是您当前所做的,并且您已经将惩罚函数定义为
    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个数字
    上限惩罚
    下限惩罚
    拉伸惩罚
    ,赋予这三个降低质量的操作不同的重要性。试试几个组合,看看哪一个效果最好。

    不知道为什么人们会对你的问题投反对票。。。我觉得很好+我同意。我认为这是一个不错的问题。我喜欢这种方法。我想引入一点权重并利用它的值实际上可能会达到目的。谢谢大家!+1现在,我实施了一个解决方案,它遵循了您的加权误差计算思想。为了使宽度/高度误差正常化,我将它们除以它们首选的宽度/高度(不确定这是否是个好主意)。所选权重为:<代码>上刻度重量=3.0f,下刻度重量=0.1f,aspectRatioWeight=2.0f。总的来说,我认为现在的结果相当不错。此外,我还添加了一个动态计算模式,以确保仅在输入值为新大小时才进行此计算。再次感谢!!