5

我目前正在使用 blobstore 为图像生成缩略图,但是,我喜欢将缩略图的尺寸存储在img标签中,因为这是一种很好的做法,有助于加快渲染速度,并使部分加载的页面看起来更好一些。

我将如何计算 blobstore 生成的缩略图的尺寸,只知道原始图像的尺寸?

我之前的尝试不是很准确,大部分时间相差一两个像素(可能是由于四舍五入)。

我知道获取缩略图而不是使用图像 API 检查尺寸会起作用,但我认为这是低效的。

这是我目前用来计算它的代码,但是,它偶尔会偏离一个像素,导致浏览器略微拉伸图像,从而导致调整大小的伪影以及性能降低。

from __future__ import division
def resized_size(original_width, original_height, width, height):
    original_ratio = float(original_width) / float(original_height)
    resize_ratio = float(width) / float(height)
    if original_ratio >= resize_ratio:
        return int(width), int(round(float(width) / float(original_ratio)))
    else:
        return int(round(float(original_ratio) * float(height))), int(height)

准确性非常重要!

4

2 回答 2

4

我看到了问题。原因是 C 的 rint 被用来计算尺寸。Python 没有与 Rossum 在 1.6 中删除的等效 rint 实现:

http://markmail.org/message/4di24iqm7zhc4rwc

你现在唯一的办法是在 python 中实现你自己的 rint。

rint 默认情况下会进行“四舍五入”与 pythons 回合,后者会执行其他操作。这是一个简单的实现(+inf -inf 等没有边缘情况处理)

import math

def rint(x):
  x_int = int(x)
  x_rem = x - x_int  # this is problematic
  if (x_int % 2) == 1:
    return round(x)
  else:
    if x_rem <= 0.5:
      return math.floor(x)
    else:
      return math.ceil(x)

上面的代码是理论上应该如何实现的。问题在于 x_rem。x - x_int 应该得到分数分量,但你可以得到分数 + delta。因此,您可以根据需要尝试添加阈值

import math

def rint(x):
  x_int = int(x)
  x_rem = x - x_int
  if (x_int % 2) == 1:
    return round(x)
  else:
    if x_rem - 0.5 < 0.001:
      return math.floor(x)
    else:
      return math.ceil(x)

这边。我硬编码了一个 0.001 的阈值。阈值本身是有问题的。我想你真的需要玩弄 rint 实现并将它适合你的应用程序,看看什么最有效。祝你好运!

于 2011-02-28T20:08:26.560 回答
0

假设您有一个 1600x1200 的原始图像并且您想要获得一个 800 大小的缩略图,那么预期的结果是一个 800x600 的图像。要计算这一点,您可以执行以下操作:

// In Java
double aspectRatio = originalWidth / originalHeight;
output_width = 800;
output_height = (int)Math.round(800.0 / aspectRatio);

让我们看看这是否适用于退化的情况。假设您有一个 145x111 的原件,并且您想要获得 32 大小的缩略图。

aspectRatio == 1.3063063063063063
output_width == 32
output_height == Math.round(32.0 / 1.3063063063063063) == 24

您可以对面向纵向的图像执行类似的操作。

于 2011-02-26T01:39:33.093 回答