How do I resize an image using PIL and maintain its aspect ratio?
是否有一种显而易见的方法可以解决这个问题? 我只是想制作缩略图。
定义最大尺寸。
然后,通过
适当的大小是
当然还有一种库方法:方法
以下是PIL文档中的(已编辑)示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import os, sys import Image size = 128, 128 for infile in sys.argv[1:]: outfile = os.path.splitext(infile)[0] +".thumbnail" if infile != outfile: try: im = Image.open(infile) im.thumbnail(size, Image.ANTIALIAS) im.save(outfile,"JPEG") except IOError: print"cannot create thumbnail for '%s'" % infile |
此脚本将使用PIL(Python成像库)调整图像(somepic.jpg)的大小,宽度为300像素,高度与新宽度成比例。它通过确定300像素的原始宽度(img.size [0])然后将原始高度(img.size [1])乘以该百分比来实现。将"basewidth"更改为任何其他数字以更改图像的默认宽度。
1 2 3 4 5 6 7 8 | from PIL import Image basewidth = 300 img = Image.open('somepic.jpg') wpercent = (basewidth/float(img.size[0])) hsize = int((float(img.size[1])*float(wpercent))) img = img.resize((basewidth,hsize), Image.ANTIALIAS) img.save('sompic.jpg') |
我还建议使用PIL的缩略图方法,因为它消除了你的所有比例麻烦。
但有一个重要提示:替换
1 | im.thumbnail(size) |
同
1 | im.thumbnail(size,Image.ANTIALIAS) |
默认情况下,PIL使用Image.NEAREST过滤器进行大小调整,从而获得良好的性能,但质量很差。
总部设在@tomvon,我完成了以下工作:
调整宽度:
1 2 | new_width = 680 new_height = new_width * height / width |
调整高度:
1 2 | new_height = 680 new_width = new_height * width / height |
然后就是:
1 | img = img.resize((new_width, new_height), Image.ANTIALIAS) |
PIL已经可以选择裁剪图像
1 | img = ImageOps.fit(img, size, Image.ANTIALIAS) |
1 2 3 4 5 6 7 | from PIL import Image img = Image.open('/your iamge path/image.jpg') # image extension *.png,*.jpg new_width = 200 new_height = 300 img = img.resize((new_width, new_height), Image.ANTIALIAS) img.save('output image name.png') # format may what u want ,*.png,*jpg,*.gif |
如果您尝试保持相同的宽高比,那么您不会调整原始大小的某个百分比吗?
例如,原始尺寸的一半
1 2 | half = 0.5 out = im.resize( [int(half * s) for s in im.size] ) |
如果您不想/不需要使用Pillow打开图像,请使用以下命令:
1 2 3 | from PIL import Image new_img_arr = numpy.array(Image.fromarray(img_arr).resize((new_width, new_height), Image.ANTIALIAS)) |
1 2 3 4 5 6 7 8 9 10 | from PIL import Image from resizeimage import resizeimage def resize_file(in_file, out_file, size): with open(in_file) as fd: image = resizeimage.resize_thumbnail(Image.open(fd), size) image.save(out_file) image.close() resize_file('foo.tif', 'foo_small.jpg', (256, 256)) |
我用这个库:
1 | pip install python-resize-image |
我试图为幻灯片视频调整一些图像的大小,因此,我不仅需要一个最大尺寸,而是最大宽度和最大高度(视频帧的大小)。
而且总是有可能拍摄肖像视频......
所以在我在这里(或者在其他地方)找不到明显的方法之后,我写了这个函数并将它放在这里以供将来使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | from PIL import Image def get_resized_img(img_path, video_size): img = Image.open(img_path) width, height = video_size # these are the MAX dimensions video_ratio = width / height img_ratio = img.size[0] / img.size[1] if video_ratio >= 1: # the video is wide if img_ratio <= video_ratio: # image is not wide enough width_new = int(height * img_ratio) size_new = width_new, height else: # image is wider than video height_new = int(width / img_ratio) size_new = width, height_new else: # the video is tall if img_ratio >= video_ratio: # image is not tall enough height_new = int(width / img_ratio) size_new = width, height_new else: # image is taller than video width_new = int(height * img_ratio) size_new = width_new, height return img.resize(size_new, resample=Image.LANCZOS) |
一种保持约束比率并传递最大宽度/高度的简单方法。不是最漂亮,但完成工作并且易于理解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | def resize(img_path, max_px_size, output_folder): with Image.open(img_path) as img: width_0, height_0 = img.size out_f_name = os.path.split(img_path)[-1] out_f_path = os.path.join(output_folder, out_f_name) if max((width_0, height_0)) <= max_px_size: print('writing {} to disk (no change from original)'.format(out_f_path)) img.save(out_f_path) return if width_0 > height_0: wpercent = max_px_size / float(width_0) hsize = int(float(height_0) * float(wpercent)) img = img.resize((max_px_size, hsize), Image.ANTIALIAS) print('writing {} to disk'.format(out_f_path)) img.save(out_f_path) return if width_0 < height_0: hpercent = max_px_size / float(height_0) wsize = int(float(width_0) * float(hpercent)) img = img.resize((max_px_size, wsize), Image.ANTIALIAS) print('writing {} to disk'.format(out_f_path)) img.save(out_f_path) return |
这是一个使用此函数运行批量图像大小调整的python脚本。
我丑陋的例子。
函数获取文件如:"pic [0-9a-z]。[extension]",将它们调整为120x120,将部分移动到中心并保存到"ico [0-9a-z]。[extension]",使用纵向和景观:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | def imageResize(filepath): from PIL import Image file_dir=os.path.split(filepath) img = Image.open(filepath) if img.size[0] > img.size[1]: aspect = img.size[1]/120 new_size = (img.size[0]/aspect, 120) else: aspect = img.size[0]/120 new_size = (120, img.size[1]/aspect) img.resize(new_size).save(file_dir[0]+'/ico'+file_dir[1][3:]) img = Image.open(file_dir[0]+'/ico'+file_dir[1][3:]) if img.size[0] > img.size[1]: new_img = img.crop( ( (((img.size[0])-120)/2), 0, 120+(((img.size[0])-120)/2), 120 ) ) else: new_img = img.crop( ( 0, (((img.size[1])-120)/2), 120, 120+(((img.size[1])-120)/2) ) ) new_img.save(file_dir[0]+'/ico'+file_dir[1][3:]) |
我以这样的方式调整了图像的大小,并且它的工作非常好
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from io import BytesIO from django.core.files.uploadedfile import InMemoryUploadedFile import os, sys from PIL import Image def imageResize(image): outputIoStream = BytesIO() imageTemproaryResized = imageTemproary.resize( (1920,1080), Image.ANTIALIAS) imageTemproaryResized.save(outputIoStream , format='PNG', quality='10') outputIoStream.seek(0) uploadedImage = InMemoryUploadedFile(outputIoStream,'ImageField',"%s.jpg" % image.name.split('.')[0], 'image/jpeg', sys.getsizeof(outputIoStream), None) ## For upload local folder fs = FileSystemStorage() filename = fs.save(uploadedImage.name, uploadedImage) |
只需使用更现代的包装器更新此问题
这个库封装了Pillow(PIL的一个分支)
https://pypi.org/project/python-resize-image/
允许你这样做: -
1 2 3 4 5 6 7 8 | from PIL import Image from resizeimage import resizeimage fd_img = open('test-image.jpeg', 'r') img = Image.open(fd_img) img = resizeimage.resize_width(img, 200) img.save('test-image-width.jpeg', img.format) fd_img.close() |
在上面的链接中添加了更多示例。