如何在保持纵横比的情况下,将肖像和横向图像调整为相同大小?
目前我正在使用:
os.chdir(album.path)
images = glob.glob('*.*')
# thumbs size
size = 80,80
for image in images:
#create thumb
file, ext = os.path.splitext(image)
im = Image.open(os.path.join(album.path,image))
im.thumbnail(size, Image.ANTIALIAS)
thumb_path = os.path.join(album.path, 'thumbs', file + ".thumb" + ".jpeg")
im.save(thumb_path)
虽然这样可以工作,但我得到的图片大小不一样(有的竖着,有的横着),我希望所有的图片都有一个固定的大小。也许可以考虑合理裁剪一下?
更新:
我不介意裁剪掉图片的一小部分。当我说合理裁剪时,我是指类似这样的算法:
if image is portrait:
make width 80px
crop the height (will be more than 80px)
else if image is landscape:
make height 80px
crop the width to 80px (will be more than 80px)
3 个回答
0
如果你使用 easy-thumbnails 这个工具,你需要把 crop
设置为 True
,同时把 upscale
也设置为 True
,这样才能确保图片总是填满空间(也就是尺寸完全一致)。
例如:让 image_2 的尺寸适应 image_1 的尺寸:
thumbnailer = get_thumbnailer(image_2)
thumbnail = thumbnailer.generate_thumbnail(thumbnail_options={
'crop': True,
'upscale': True,
'size': image_1.size
})
image_2 = thumbnail.image
2
显然,你需要对图片进行裁剪或填充。你可以尝试下面的方式,根据缩略图的宽高比来获得一个最大化的居中裁剪(这个代码没有经过测试):
aspect = lambda size: float(size[0]) / float(size[1])
sa = aspect(size)
if aspect(im.size) > sa:
width = int(sa * im.size[1])
left = (im.size[0] - width) / 2
im = im.crop((left, 0, left + width, im.size[1]))
else:
height = int(im.size[0] / sa)
top = (im.size[1] - height) / 2
im = im.crop((0, top, im.size[0], top + height))
im.thumbnail(size, Image.ANTIALIAS)
19
这是我对给图片加边距适配的看法:
#!/usr/bin/env python
from PIL import Image, ImageChops
F_IN = "/path/to/image_in.jpg"
F_OUT = "/path/to/image_out.jpg"
size = (80,80)
image = Image.open(F_IN)
image.thumbnail(size, Image.ANTIALIAS)
image_size = image.size
thumb = image.crop( (0, 0, size[0], size[1]) )
offset_x = max( (size[0] - image_size[0]) / 2, 0 )
offset_y = max( (size[1] - image_size[1]) / 2, 0 )
thumb = ImageChops.offset(thumb, offset_x, offset_y)
thumb.save(F_OUT)
首先,它使用缩略图操作把图片缩小到原始范围内,同时保持图片的比例。接着,它会把图片裁剪回来,以便真正填满你的设定大小(因为如果原始图片不是正方形,缩小后就会变小),然后我们找到合适的偏移量来让图片居中。这样,图片就会偏移到中心位置,最终效果是有黑色边距,但不会裁剪掉图片的内容。
除非你能很准确地猜出一个合适的中心裁剪位置,而不损失可能在边缘的重要图片数据,否则使用加边距的适配方式会更好。
更新
这里有一个版本,可以选择中心裁剪或者加边距适配。
#!/usr/bin/env python
from PIL import Image, ImageChops, ImageOps
def makeThumb(f_in, f_out, size=(80,80), pad=False):
image = Image.open(f_in)
image.thumbnail(size, Image.ANTIALIAS)
image_size = image.size
if pad:
thumb = image.crop( (0, 0, size[0], size[1]) )
offset_x = max( (size[0] - image_size[0]) / 2, 0 )
offset_y = max( (size[1] - image_size[1]) / 2, 0 )
thumb = ImageChops.offset(thumb, offset_x, offset_y)
else:
thumb = ImageOps.fit(image, size, Image.ANTIALIAS, (0.5, 0.5))
thumb.save(f_out)
source = "/path/to/source/image.JPG"
makeThumb(source, "/path/to/source/image_padded.JPG", pad=True)
makeThumb(source, "/path/to/source/image_centerCropped.JPG", pad=False)