【问题标题】:App Engine: Calculating the dimensions of thumbnails to be generated by serving thumbnails from the blobstoreApp Engine:通过从 blobstore 提供缩略图来计算要生成的缩略图的尺寸
【发布时间】:2011-07-02 01:21:50
【问题描述】:

我目前正在使用 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)

准确性非常重要!

【问题讨论】:

  • 好问题!你尝试了什么公式,在什么情况下它是错误的?
  • @systempuntoout,我没有生成它们,Google 的图像服务 API 是,它不提供尺寸。 @Nick Johnson,我用我目前使用的代码更新了我的问题。

标签: python google-app-engine thumbnails blobstore


【解决方案1】:

我看到了问题。原因是 C 的 rint 被用来计算 尺寸。 Python 没有等效的 rint 实现 正如 Rossum 在 1.6 中取出的那样:

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 应该得到小数分量,但是你可以得到 分数 + 增量。因此,您可以根据需要尝试添加阈值

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 实现并适应它 到您的应用程序,看看什么最有效。祝你好运!

【讨论】:

  • 我对rint不熟悉,如何在Python中实现?
【解决方案2】:

假设您有一个 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

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

【讨论】:

    猜你喜欢
    • 2018-09-04
    • 2019-08-10
    • 2011-04-03
    • 2013-07-21
    • 2014-04-18
    • 2014-09-10
    • 2014-02-24
    • 2012-10-30
    • 2012-04-20
    相关资源
    最近更新 更多