2008-11-07 37 views
266

Có cách nào rõ ràng để làm điều này mà tôi đang thiếu? Tôi chỉ đang cố tạo hình thu nhỏ.Làm cách nào để thay đổi kích thước hình ảnh bằng PIL và duy trì tỷ lệ khung hình?

+7

Kể từ khi câu hỏi này là khá cũ nhưng hữu ích, và gối được khá ưa thích, cho một hướng dẫn gối dựa trên hãy xem này: http : //pillow.readthedocs.org/en/latest/handbook/tutorial.html#create-jpeg-thumbnails – Wtower

+1

Tôi đã tạo một thư viện nhỏ để định lại kích thước hình ảnh, nó có thể có bất kỳ trợ giúp nào: https://github.com/ charlesthk/python-resize-image – Charlesthk

Trả lời

326

Xác định kích thước tối đa. Sau đó, tính tỷ lệ thay đổi kích thước bằng cách lấy min(maxwidth/width, maxheight/height).

Kích thước phù hợp là oldsize*ratio.

Có tất nhiên cũng là một phương pháp thư viện để thực hiện việc này: phương pháp Image.thumbnail.
Dưới đây là một ví dụ (đã chỉnh sửa) từ PIL documentation.

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 
+58

** Nhận xét của [Randy Syring] (http://stackoverflow.com/users/182111/randy-syring) **: Thêm 'Image.ANTIALIAS' vào cuộc gọi' thumbnail() '. Nó rất khuyến khích trong các tài liệu và với điều này là câu trả lời hàng đầu, nên thực hành tốt nhất. Nói cách khác: Thay thế 'im.thumbnail (size)' bằng 'im.thumbnail (size, Image.ANTIALIAS)'. – Anne

+2

Giống như nó nói, ví dụ là từ tài liệu hướng dẫn pil, và ví dụ đó (vẫn) không sử dụng cờ antialias. Vì nó có lẽ là những gì hầu hết mọi người sẽ muốn, mặc dù, tôi đã thêm nó. – gnud

+2

PIL đặt chiều cao của hình ảnh mới theo kích thước đã cho (128 ở đây) và tính chiều rộng để giữ tỷ lệ cỡ ảnh. Có cách nào để sửa chiều rộng thay vì chiều cao không? có lẽ tôi sẽ hỏi điều này trong câu hỏi riêng. – eugene

9

Nếu bạn đang cố gắng duy trì cùng tỷ lệ khung hình, bạn sẽ không thay đổi kích thước một phần trăm kích thước ban đầu?

Ví dụ, một nửa kích thước ban đầu

half = 0.5 
out = im.resize([int(half * s) for s in im.size]) 
+7

Có thể là hình ảnh có kích thước khác nhau và kết quả thay đổi kích thước được yêu cầu phải có kích thước đồng nhất – Steen

136

Kịch bản này sẽ thay đổi kích thước một hình ảnh (somepic.jpg) sử dụng PIL (Python Imaging Library) để có chiều rộng 300 pixel và chiều cao tương ứng với chiều rộng mới . Nó thực hiện điều này bằng cách xác định tỷ lệ phần trăm 300 pixel của chiều rộng ban đầu (img.size [0]) và sau đó nhân chiều cao ban đầu (img.size [1]) với tỷ lệ phần trăm đó. Thay đổi "basewidth" thành bất kỳ số nào khác để thay đổi độ rộng mặc định của hình ảnh của bạn.

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') 
+2

Nếu bạn đang sử dụng tập lệnh này trong Zope dưới dạng phương thức bên ngoài, bạn sẽ cần dòng "từ hình ảnh nhập PIL" để tránh xung đột không gian tên với "Hình ảnh" của Zope. – tomvon

+1

cảm ơn cho 'PIL.Image.ANTIALIAS' –

+0

Mã này cho tôi một tập tin đầu ra 0 byte' '' sompic.jpg'''. Lý do tại sao điều này xảy ra? Tôi đang sử dụng Python 3.x –

46

Tôi cũng khuyên bạn nên sử dụng phương pháp thu nhỏ của PIL, vì nó loại bỏ tất cả các tỷ lệ phức tạp của bạn.

Một gợi ý quan trọng, mặc dù: Thay thế

im.thumbnail(size) 

với

im.thumbnail(size,Image.ANTIALIAS) 

theo mặc định, PIL sử dụng bộ lọc Image.NEAREST cho thay đổi kích thước mà kết quả trong việc thực hiện tốt, nhưng chất lượng kém.

13

PIL đã có tùy chọn để cắt một hình ảnh

img = ImageOps.fit(img, size, Image.ANTIALIAS) 
+10

Điều đó chỉ cắt hình ảnh, nó không duy trì tỷ lệ khung hình. – Radu

1

dụ xấu xí của tôi.

Chức năng nhận tệp như: "pic [0-9a-z]. [Extension]", đổi kích thước chúng thành 120x120, di chuyển phần đến giữa và lưu vào "ico [0-9a-z].[Mở rộng]", làm việc với dọc và ngang:

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:]) 
17

Có trụ sở tại @tomvon, tôi đã hoàn thành bằng cách sử dụng như sau: chiều rộng

Thay đổi kích thước:

new_width = 680 
new_height = new_width * height/width 

Thay đổi kích thước chiều cao:

new_height = 680 
new_width = new_height * width/height 

Sau đó chỉ cần:

img = img.resize((new_width, new_height), Image.ANTIALIAS) 
+4

Các biến của bạn đều bị lẫn lộn. Bài đăng của bạn cho biết thay đổi kích thước chiều rộng và sau đó thay đổi kích thước chiều cao. Và trong cuộc gọi 'resize', bạn đang sử dụng' new_width' cho cả chiều cao và chiều rộng? – Zachafer

+0

Đề xuất sửa chữa cho @Zachafer đó – Mohammad

2
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)) 

tôi sử dụng thư viện này:

pip install python-resize-image 
8
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 
Các vấn đề liên quan