Notice how for every image that google indexes it has a small thumbnail. These thumbnails are:
请注意,谷歌索引的每个图片都有一个小缩略图。这些缩略图是:
- Less than 10KB in size.
- The proportions of the width / height are the same as the ones in the original image.
小于10KB。
宽度/高度的比例与原始图像中的比例相同。
I would like to write a function (in python) that would take an image and create a thumbnail with these to properties.
我想编写一个函数(在python中),它将获取图像并使用这些属性创建缩略图。
EDIT: So there are 3 answers right now and all of them are half right.
编辑:所以现在有3个答案,所有答案都是对的。
I need a function that not only resizes the image proportionally, but also makes sure the file size is smaller than 10KB. How do I do that?
我需要一个功能,不仅可以按比例调整图像大小,还可以确保文件大小小于10KB。我怎么做?
3 个解决方案
#1
In this short post, Mike Fletcher and the effbot show (and discuss detailed variation) an excellent approach for the task you want to do.
在这篇短文中,Mike Fletcher和effbot展示(并讨论详细的变化)是您想要完成的任务的绝佳方法。
Edit: as for the 10K requirement, it's hard (to say the least;-) to predict how well an image will compress, depending on the image's format, since today's compression algorithms are so subtle. If you want your thumbnail to be just about as large (in pixels) as feasible while respecting a <10K requirement, you may have to use a "trial and error" approach making successively more refined guesses about the scaling factor, until you reach an acceptable result.
编辑:对于10K的要求,很难(至少可以说;-)来预测图像压缩的程度,这取决于图像的格式,因为今天的压缩算法非常微妙。如果您希望缩略图在满足<10K要求的同时尽可能大(以像素为单位),则可能必须使用“反复试验”方法对缩放因子进行连续更精确的猜测,直到达到可接受的结果
For example, here's a "binary search" approach to getting the correct size (there may well be better strategies!), with ample print statements &c to explain what's going on...:
例如,这里是一个“二元搜索”方法来获得正确的大小(可能有更好的策略!),有足够的打印语句和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()
#2
Did you read the PIL documentation? There is an image.thumbnail method.
你读过PIL文件了吗?有一个image.thumbnail方法。
#3
Use PIL, see sample code here to resize keeping aspect ratio
使用PIL,请参阅此处的示例代码以调整保持纵横比
How do I resize an image using PIL and maintain its aspect ratio?
如何使用PIL调整图像大小并保持其纵横比?
see how to do similar thing on a dir
看看如何在dir上做类似的事情
调整目录中的图像大小
So above links describe how to resize images using PIL, now coming to your question of max size of 10KB, that can be achieved easily e.g.
所以上面的链接描述了如何使用PIL调整图像大小,现在出现了最大10KB的问题,这可以很容易地实现,例如
Suppose size required is 100x100, and we use JPEG compression, 100% JPEG quality takes abt 9 bits per pixel(see http://en.wikipedia.org/wiki/JPEG), that means size of 100x100 image would be 100x100x9/(1024x8) = 11KB, so at quality=100 you are almost achieving your goal, but if you still want 10KB only you can set quality=90, and in general you can pass quality as param to resize function and reduce quality by 10% if image size is above 10KB but I think that is not needed, at 90% quality all JPEG images would be < 10KB.
假设所需的大小是100x100,我们使用JPEG压缩,100%JPEG质量每像素需要9位(参见http://en.wikipedia.org/wiki/JPEG),这意味着100x100图像的大小将是100x100x9 /( 1024x8)= 11KB,所以在质量= 100时,你几乎达到了你的目标,但如果你仍然只想要10KB,你可以设置质量= 90,一般来说你可以通过质量作为参数来调整功能,并将质量降低10%图像大小超过10KB,但我认为不需要,90%的质量,所有JPEG图像将<10KB。
Also note that without compression also image size is just 30KB for RGB image, and if you reduce size to 60x60 pixels image size would be only 10KB without any compression i.e you can use bmp images and if you want lesses sizer but lossless compression you can choose PNG.
另请注意,如果没有压缩,RGB图像的图像大小也只有30KB,如果将尺寸减小到60x60像素,图像尺寸只有10KB而没有任何压缩,即你可以使用bmp图像,如果你想要lers sizer但无损压缩,你可以选择PNG。
So in conclusion your target of 10KB is very easy to achieve.
总而言之,您的10KB目标很容易实现。
#1
In this short post, Mike Fletcher and the effbot show (and discuss detailed variation) an excellent approach for the task you want to do.
在这篇短文中,Mike Fletcher和effbot展示(并讨论详细的变化)是您想要完成的任务的绝佳方法。
Edit: as for the 10K requirement, it's hard (to say the least;-) to predict how well an image will compress, depending on the image's format, since today's compression algorithms are so subtle. If you want your thumbnail to be just about as large (in pixels) as feasible while respecting a <10K requirement, you may have to use a "trial and error" approach making successively more refined guesses about the scaling factor, until you reach an acceptable result.
编辑:对于10K的要求,很难(至少可以说;-)来预测图像压缩的程度,这取决于图像的格式,因为今天的压缩算法非常微妙。如果您希望缩略图在满足<10K要求的同时尽可能大(以像素为单位),则可能必须使用“反复试验”方法对缩放因子进行连续更精确的猜测,直到达到可接受的结果
For example, here's a "binary search" approach to getting the correct size (there may well be better strategies!), with ample print statements &c to explain what's going on...:
例如,这里是一个“二元搜索”方法来获得正确的大小(可能有更好的策略!),有足够的打印语句和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()
#2
Did you read the PIL documentation? There is an image.thumbnail method.
你读过PIL文件了吗?有一个image.thumbnail方法。
#3
Use PIL, see sample code here to resize keeping aspect ratio
使用PIL,请参阅此处的示例代码以调整保持纵横比
How do I resize an image using PIL and maintain its aspect ratio?
如何使用PIL调整图像大小并保持其纵横比?
see how to do similar thing on a dir
看看如何在dir上做类似的事情
调整目录中的图像大小
So above links describe how to resize images using PIL, now coming to your question of max size of 10KB, that can be achieved easily e.g.
所以上面的链接描述了如何使用PIL调整图像大小,现在出现了最大10KB的问题,这可以很容易地实现,例如
Suppose size required is 100x100, and we use JPEG compression, 100% JPEG quality takes abt 9 bits per pixel(see http://en.wikipedia.org/wiki/JPEG), that means size of 100x100 image would be 100x100x9/(1024x8) = 11KB, so at quality=100 you are almost achieving your goal, but if you still want 10KB only you can set quality=90, and in general you can pass quality as param to resize function and reduce quality by 10% if image size is above 10KB but I think that is not needed, at 90% quality all JPEG images would be < 10KB.
假设所需的大小是100x100,我们使用JPEG压缩,100%JPEG质量每像素需要9位(参见http://en.wikipedia.org/wiki/JPEG),这意味着100x100图像的大小将是100x100x9 /( 1024x8)= 11KB,所以在质量= 100时,你几乎达到了你的目标,但如果你仍然只想要10KB,你可以设置质量= 90,一般来说你可以通过质量作为参数来调整功能,并将质量降低10%图像大小超过10KB,但我认为不需要,90%的质量,所有JPEG图像将<10KB。
Also note that without compression also image size is just 30KB for RGB image, and if you reduce size to 60x60 pixels image size would be only 10KB without any compression i.e you can use bmp images and if you want lesses sizer but lossless compression you can choose PNG.
另请注意,如果没有压缩,RGB图像的图像大小也只有30KB,如果将尺寸减小到60x60像素,图像尺寸只有10KB而没有任何压缩,即你可以使用bmp图像,如果你想要lers sizer但无损压缩,你可以选择PNG。
So in conclusion your target of 10KB is very easy to achieve.
总而言之,您的10KB目标很容易实现。