2009-07-02 65 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的目標很容易實現。