2012-05-16 10 views
30

Có giải pháp đơn giản nào để cắt khoảng trắng trên hình ảnh trong PIL không?Cắt khoảng trống bằng cách sử dụng PIL

ImageMagick có hỗ trợ dễ dàng cho nó theo cách sau:

convert test.jpeg -fuzz 7% -trim test_trimmed.jpeg 

Tôi tìm thấy một giải pháp cho PIL:

from PIL import Image, ImageChops 

def trim(im, border): 
    bg = Image.new(im.mode, im.size, border) 
    diff = ImageChops.difference(im, bg) 
    bbox = diff.getbbox() 
    if bbox: 
     return im.crop(bbox) 

Nhưng giải pháp này có nhược điểm:

  1. tôi cần phải xác định border màu sắc, nó không phải là một việc lớn đối với tôi, hình ảnh của tôi có nền trắng
  2. Và bất lợi nhất, giải pháp PIL này không hỗ trợ khóa -fuzz của ImageMagick. Để thêm một số cắt xén mờ. vì tôi có thể có một số đồ tạo tác nén jpeg và các bóng lớn không cần thiết.

Có thể PIL có một số chức năng được tích hợp sẵn cho nó? Hoặc có một số giải pháp nhanh?

+1

tôi biết mã là giống hệt nhau ở đó, nhưng nó cũng có thể được tìm thấy ở đây - https://gist.github.com/mattjmorrison/932345 –

Trả lời

74

Tôi không nghĩ có bất kỳ thứ gì được tích hợp vào PIL có thể thực hiện việc này. Nhưng tôi đã sửa đổi mã của bạn để nó sẽ làm điều đó.

  • Nó có màu đường viền từ pixel trên cùng bên trái, sử dụng getpixel, vì vậy bạn không cần phải chuyển màu.
  • Trừ một vô hướng từ hình ảnh khác biệt, đây là cách nhanh chóng bão hòa tất cả các giá trị dưới 100, 100, 100 (trong ví dụ của tôi) về 0. Vì vậy, là một cách gọn gàng để loại bỏ bất kỳ 'lung lay' do nén.

Code:

from PIL import Image, ImageChops 

def trim(im): 
    bg = Image.new(im.mode, im.size, im.getpixel((0,0))) 
    diff = ImageChops.difference(im, bg) 
    diff = ImageChops.add(diff, diff, 2.0, -100) 
    bbox = diff.getbbox() 
    if bbox: 
     return im.crop(bbox) 

im = Image.open("bord3.jpg") 
im = trim(im) 
im.show() 

nặng nề nén jpeg:

enter image description here cắt: enter image description here

jpeg ồn ào:

enter image description here cắt: enter image description here

+4

Đây là được tôi đang tìm kiếm. Nó hoạt động như một phép thuật. Cảm ơn. –

+0

@Ideviantik - tuyệt, tôi hơi đơn giản hóa nó. thưởng thức. – fraxel

+5

Lưu ý rằng thao tác bạn đang làm rất nguy hiểm: nó bù cho nhiễu ở biên giới, nhưng bạn không còn có thể xử lý hình ảnh nơi nền và hình ảnh của nó rất giống nhau - ví dụ ảnh nếu bài viết màu trắng được đặt trên nền trắng. –

2

Sử dụng cây đũa phép http://docs.wand-py.org/en/0.3-maintenance/wand/image.html

trim (color = None, fuzz = 0) Xóa đường viền rắn khỏi hình ảnh. Sử dụng pixel trên cùng bên trái làm hướng dẫn theo mặc định hoặc bạn cũng có thể chỉ định màu cần xóa.

1

sử dụng chức năng cắt tại mô-đun ufp.image.

import ufp.image 
import PIL 
im = PIL.Image.open('test.jpg', 'r') 
trimed = ufp.image.trim(im, fuzz=13.3) 
trimed.save('trimed.jpg') 

xem ví dụ: Trim image edge whitespace with fuzz [Python]

+1

Liên kết đó trong câu trả lời của bạn bây giờ chuyển tiếp sang tệp tải xuống 1gb. Có thể là một ý tưởng hay để loại bỏ nó. –