Как эффективно обрезать прозрачные границы моего изображения? - PullRequest
0 голосов
/ 21 апреля 2019

Я хочу автоматизировать процесс обрезки прозрачных краев из изображений PNG с помощью Node.js, а точнее с помощью инструмента CLI (называемого child_process ) или модуля Node с собственными привязками, а не с чистыми Реализация JavaScript по соображениям производительности.

Это звучит как довольно простая задача, но я ищу недели без результатов, которые соответствуют моим потребностям.

  • Процедура обрезки должна искать прозрачные пиксели независимо от того, как выглядит входное изображение. В большинстве реализаций проверяется цвет верхнего левого пикселя.
  • Процедура обрезки должна быть настраиваемой со значением допуска, поэтому удаляется все, что с непрозрачностью 20% или менее, вместо строгой проверки на непрозрачность 0%.

В настоящее время я использую Sharp и GraphicsMagick для сложной цепочки манипуляций с изображениями, но поскольку я не нашел инструмента для обрезки прозрачности, я написал пользовательский Jimp плагин, который обрабатывает задания обрезки довольно неэффективно, но все еще работает.

Вот пример входного изображения:

https://i.imgur.com/E1j6NjP.png

и ожидаемое выходное изображение:

https://i.imgur.com/3k9V2ac.png

Хотя я хочу избавиться от Jimp.

1 Ответ

0 голосов
/ 27 апреля 2019

libvips , библиотека обработки изображений, используемая Sharp, имеет find_trim.

В вашем случае вы хотите протестировать только альфа-канал (полоса 3), поэтому извлеките его и найдите ограничивающий прямоугольник ненулевых значений:

$ vips extract_band test-transparency.png x.png 3
$ vips find_trim x.png --background 0 --threshold 20
0
0
722
639

И это осталось / верх / ширина / высота области, которую вы хотите. Вы можете вырезать это из вашего исходного изображения с помощью:

$ vips crop test-transparency.png y.png 0 0 722 639

Сделать:

sample output

Вы можете сделать это как однострочник с:

$ vips crop test-transparency.png y.png $(vips extract_band test-transparency.png x.png 3; vips find_trim x.png --background 0 --threshold 20)

Вы можете сделать его немного более эффективным в Python:

#!/usr/bin/python3

import sys
import pyvips

image = pyvips.Image.new_from_file(sys.argv[1])
left, top, width, height = image[3].find_trim(background=0, threshold=20)
image = image.crop(left, top, width, height)
image.write_to_file(sys.argv[2])

И раскошелиться на это. Конечно, вы можете не захотеть добавлять py как зависимость.

...