2011-02-22 101 views
5

我目前使用Blobstore为图像生成缩略图,但是,我喜欢将缩略图的尺寸存储在img标记中,因为这是很好的做法,有助于加快渲染速度,并使部分加载的页面看起来更漂亮一些。App Engine:计算从Blobstore服务缩略图生成缩略图的尺寸

我该如何计算由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) 

准确性非常重要!

+1

好问题!你尝试了什么公式?在什么情况下错了? –

+0

@systempuntoout,我没有生成它们,Google的图片服务API是,它不提供维度。 @Nick Johnson,我用我目前使用的代码更新了我的问题。 –

回答

4

我看到了问题。原因是C的rint被用来计算 的尺寸。 Python没有一个相当于RINT实现 因为它是在1.6取出由Rossum的:

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

你只有靠现在的问题是要在Python中实现自己的RINT。

默认情况下,rint默认会执行“round to even”,而python会执行其他操作。 下面是一个简单的实现(没有边缘的情况下的处理为+ 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的实现,并将其适用于你的应用程序,并看看什么效果最好。祝你好运!

+0

我不熟悉rint,我将如何在Python中实现它? –

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 

您可以对纵向图像做类似的事情。