2009-12-15 3 views
7

Как отрезать пустую область границы изображения PNG и сжать ее до минимального размера с помощью Python?Обрезать изображение PNG до минимального размера

+0

Является ли размер области границы статичным? Если это так, вы можете попробовать использовать привязки python ImageMagick. – Qberticus

+0

размер пустой границы не является фиксированным значением, оно зависит от каждого изображения. – jack

ответ

13

PIL «ы getbbox работает для меня

im.getbbox() => 4-кортежа или None

Вычисляет ограничительную рамку из ненулевых областей в изображении. Ограничивающий прямоугольник возвращается как 4-кортеж , определяющий координату нижнего пикселя слева, сверху, справа и . Если изображение полностью пустое, этот метод возвращает None.

Образец кода, который я пробовал, я тестировал с BMP, но он должен работать и для png.

>>> import Image 
>>> im=Image.open("test.bmp") 
>>> im.size 
(364, 471) 
>>> im.getbbox() 
(64, 89, 278, 267) 
>>> im2=im.crop(im.getbbox()) 
>>> im2.size 
(214, 178) 
>>> im2.save("test2.bmp") 
1

Вы можете использовать PIL, чтобы найти строки и столбцы вашего изображения, которые составлены исключительно из вашего цвета границы.

Используя эту информацию, вы можете легко определить экстенты инкрустации изображения.

PIL снова позволит вам обрезать изображение, чтобы удалить границу.

3

https://gist.github.com/3141140

import Image 
import sys 
import glob 

# Trim all png images with alpha in a folder 
# Usage "python PNGAlphaTrim.py ../someFolder" 

try: 
    folderName = sys.argv[1] 
except : 
    print "Usage: python PNGPNGAlphaTrim.py ../someFolder" 
    sys.exit(1) 

filePaths = glob.glob(folderName + "/*.png") #search for all png images in the folder 

for filePath in filePaths: 
    image=Image.open(filePath) 
    image.load() 

    imageSize = image.size 
    imageBox = image.getbbox() 

    imageComponents = image.split() 

    if len(imageComponents) < 4: continue #don't process images without alpha 

    rgbImage = Image.new("RGB", imageSize, (0,0,0)) 
    rgbImage.paste(image, mask=imageComponents[3]) 
    croppedBox = rgbImage.getbbox() 

    if imageBox != croppedBox: 
     cropped=image.crop(croppedBox) 
     print filePath, "Size:", imageSize, "New Size:",croppedBox 
     cropped.save(filePath) 
0

Я считаю, что необходимо дополнить ответ @Frank Крюгера. Он делает хороший момент, но не включает в себя, как правильно обрезать дополнительный цвет границы из изображения. Я обнаружил, что here. В частности, я нашел это полезным:

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() 
+0

Хотя эта ссылка может ответить на вопрос, лучше включить здесь основные части ответа и предоставить ссылку для справки. Ответные ссылки могут стать недействительными, если связанная страница изменится. - [Из обзора] (/ review/low-quality-posts/11453172) – niton

+0

Отредактировано для включения определенного кода. Хорошая точка зрения. – AaronJPung

2

У меня была такая же проблема сегодня. Вот мое решение для обрезки прозрачных границ. Просто бросьте этот скрипт в свою папку с вашими пакетными файлами .png:

from PIL import Image 
import numpy as np 
from os import listdir 

def crop(png_image_name): 
    pil_image = Image.open(png_image_name) 
    np_array = np.array(pil_image) 
    blank_px = [255, 255, 255, 0] 
    mask = np_array != blank_px 
    coords = np.argwhere(mask) 
    x0, y0, z0 = coords.min(axis=0) 
    x1, y1, z1 = coords.max(axis=0) + 1 
    cropped_box = np_array[x0:x1, y0:y1, z0:z1] 
    pil_image = Image.fromarray(cropped_box, 'RGBA') 
    print(pil_image.width, pil_image.height) 
    pil_image.save(png_image_name) 
    print(png_image_name) 

for f in listdir('.'): 
    if f.endswith('.png'): 
     crop(f) 
Смежные вопросы