调整图像保持纵横比并使纵向和横向图像完全相同的大小?

thy*_*agx 11 python django image thumbnails python-imaging-library

目前我正在使用:

    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)
Run Code Online (Sandbox Code Playgroud)

虽然这有效,但我最终得到了不同尺寸的图像(有些是肖像,有些是风景),但我希望所有图像都具有精确的尺寸.也许是一个明智的裁剪?

更新:

我不介意裁剪一小部分图像.当我说明智的裁剪时,我的意思是这样的algorythm:

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)
Run Code Online (Sandbox Code Playgroud)

jdi*_*jdi 18

这是我对图像进行填充拟合的看法:

#!/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)
Run Code Online (Sandbox Code Playgroud)

它首先使用缩略图操作将图像降低到原始边界内并保留方面.然后将它裁剪回来以实际填充边界的大小(因为除非原始图像是正方形,现在它将更小),并且我们找到适当的偏移以使图像居中.图像偏移到中心,因此您最终得到黑色填充但没有图像裁剪.

除非您能够在适当的中心裁剪上做出真正合理的猜测而不会丢失边缘上可能的重要图像数据,否则填充拟合方法将更好地工作.

更新

这是一个可以做中心裁剪或打击垫配合的版本.

#!/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)
Run Code Online (Sandbox Code Playgroud)