2009-07-02 68 views
1

请注意,Google索引它的每个图像的小型图像尺寸为thumbnail。 这些缩略图是:生成小于10KB的图像缩略图,并且不会丢失比例

  1. 小于10KB的大小。
  2. 宽度/高度的比例与原始图像中的比例相同。

我想写一个函数(在python中),它将拍摄一张图像并创建一个带有这些属性的缩略图。

编辑: 所以现在有3个答案,他们都是一半的权利。

我需要一个函数,不仅可以按比例调整图像大小,还可以确保文件大小小于10KB。我怎么做?

+0

重复:http://stackoverflow.com/questions/273946/how-do-i-resize-an-image-using-pil-and-maintain-its-aspect-ratio – 2009-07-02 16:12:21

回答

3

this short post中,Mike Fletcher和effbot节目(并讨论详细变体)是您想要完成的任务的绝佳方法。

编辑:至于10K的要求,根据图像的格式,很难(至少可以说;-)来预测图像压缩的程度,因为今天的压缩算法非常微妙。如果您希望您的缩略图尽可能大(以像素为单位),同时考虑到要求,您可能需要使用“试错法”方法,对缩放因子进行更精确的猜测,直到您到达可接受的结果

例如,这里有一个“二进制搜索”的方法来得到正确的尺寸(有可能是更好的策略!),有充足的print语句& C到解释这是怎么回事...:

import Image 
import cStringIO 
import math 
import os 
import stat 

# try no more than 10 times, then give up 
MAX_TRIES = 10 

def getThumbnail(filename, max_bytes=(10*1024)): 
    '''Get a thumbnail image of filename, <max_bytes''' 
    original_size = os.stat(filename)[stat.ST_SIZE] 
    print "Original file size: %.1f KB" % (original_size/1024.) 
    image = Image.open(filename) 
    image.load() 
    print "Original image size: %dx%d pixels" % image.size 
    min_bytes = int(0.9 * max_bytes) 
    largest_side = max(image.size) 
    smallest_side = 16 
    for attempt in range(MAX_TRIES): 
     try_side = (largest_side + smallest_side)/2 
    print "Attempt #%d of %d" % (attempt+1, MAX_TRIES) 
    print "Side must be within [%d:%d], now trying %d" % (
     smallest_side, largest_side, try_side) 
    thumb = image.copy() 
    thumb.thumbnail((try_side,try_side), Image.ANTIALIAS) 
    afile = cStringIO.StringIO() 
    thumb.save(afile, "PNG") 
    resulting_size = len(afile.getvalue()) 
    afile.close() 
    print "Reduced file size: %.1f KB" % (resulting_size/1024.) 
    print "Reduced image size: %dx%d pixels" % thumb.size 
    if min_bytes <= resulting_size <= max_bytes: 
     print "Success!" 
     return thumb 
    elif resulting_size > max_bytes: 
     print "Too large (>%d), reducing more" % max_bytes 
     largest_side = try_side 
    else: 
     print "Too small (<%d), reducing less" % min_bytes 
     smallest_side = try_side 
    print "too many attempts, returning what I've got!" 
    return thumb 

def main(): 
    thumb = getThumbnail("pyth.png") 
    print "Reduced image size: %dx%d pixels" % thumb.size 
    print "Saving to thumb.png" 
    thumb.save("thumb.png") 
    thumb_size = os.stat("thumb.png")[stat.ST_SIZE] 
    print "Reduced file size: %.1f KB" % (thumb_size/1024.) 
    print "Done, bye!" 

if __name__ == '__main__': 
    main() 
1

使用PIL,见示例代码这里来调整保持长宽比

How do I resize an image using PIL and maintain its aspect ratio?

看看如何做一个目录类似的事情

Resize images in directory

因此,上面的链接描述了如何使用PIL调整图像大小,现在来到您的最大大小为10KB的问题,这可以很容易地实现,例如,我们使用JPEG压缩,100%JPEG质量需要每像素9位(请参阅http://en.wikipedia.org/wiki/JPEG),这意味着100x100图像的尺寸应为100x100x9 /(1024x8)= 11KB,因此在质量= 100你几乎实现了你的目标,但是如果你仍然只需要10KB,你可以设置质量= 90,并且一般来说你可以传递质量作为参数来调整函数大小,如果图像大小超过10KB,则质量降低10%,但我认为这是不需要的,在90%质量下,所有JPEG图像将是< 10KB。

还要注意的是,如果不进行压缩,RGB图像的图像大小也只有30KB,如果将大小减小到60x60像素,则图像大小将只有10KB而没有任何压缩,即,您可以使用bmp图像,并且如果要使用sizer但无损压缩你可以选择PNG。

因此总的来说你的10KB的目标很容易实现。