Как обрезать пустую область границы изображения PNG и уменьшить ее до минимального размера с помощью Python?
Обрезать изображение PNG до минимального размера
Ответы (6)
im.getbbox () => 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")
Сегодня у меня была такая же проблема. Вот мое решение для обрезки прозрачных границ. Просто киньте этот скрипт в свою папку с вашими пакетными файлами .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)
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)
Вот готовое решение:
import numpy as np
from PIL import Image
def bbox(im):
a = np.array(im)[:,:,:3] # keep RGB only
m = np.any(a != [255, 255, 255], axis=2)
coords = np.argwhere(m)
y0, x0, y1, x1 = *np.min(coords, axis=0), *np.max(coords, axis=0)
return (x0, y0, x1+1, y1+1)
im = Image.open('test.png')
print(bbox(im)) # (33, 12, 223, 80)
im2 = im.crop(bbox(im))
im2.save('test_cropped.png')
Пример ввода (ссылка для скачивания, если вы хотите попробовать):
Вывод:
Вы можете использовать PIL, чтобы найти строки и столбцы вашего изображения, состоящие исключительно из ваших цвет границы.
Используя эту информацию, вы можете легко определить размеры инкрустированного изображения.
PIL снова позволит вам обрезать изображение, чтобы удалить границу.
Я считаю необходимым дополнить ответ @Frank Krueger. Он хорошо замечает, но в нем не говорится о том, как правильно обрезать лишний цвет границы изображения. Я обнаружил, что здесь. В частности, я нашел это полезным:
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()