Обнаружение альфа-канала с помощью ImageMagick

Сценарий

Я хотел бы сохранить изображения с альфа-прозрачностью как .png и изображения без альфа-прозрачности как .jpg (даже если их исходный формат - .png или .gif). Как с помощью ImageMagick определить, имеет ли изображение альфа-прозрачность?


person brad    schedule 05.04.2010    source источник


Ответы (6)


Команда ImageMagik:

identify -format '%[channels]' foo.png 

напечатает rgba или rgb, если есть или нет альфа-канал, соответственно.

Может присутствовать альфа-канал без данных, в котором на самом деле не было бы прозрачности, но это немного сложнее.

person msw    schedule 05.04.2010
comment
Является ли альфа-канал без данных обычным явлением? Если да, могу я это узнать? - person brad; 06.04.2010
comment
По моему опыту, люди создают альфа-каналы только тогда, когда хотят, чтобы они были непустыми, но есть разница между тем, что обычно происходит, и тем, что может случиться. Я бы не стал беспокоиться об этом, если вы не обнаружите, что это всплывает. Я просто пытался быть полным, отметив, что существование альфа-канала не обязательно подразумевает наличие прозрачности. - person msw; 06.04.2010
comment
О да. Никогда не недооценивайте пользователя. Спасибо! - person brad; 06.04.2010
comment
Конечно, это очень старый вопрос, но отсутствие альфа-канала не означает отсутствие альфа-пикселей. Можно иметь индексированный RGB png с полностью прозрачными некоторыми элементами индекса. См. TRNS в документации png. - person OmnipotentEntity; 17.01.2012

Проверьте, есть ли у изображения альфа-канал

Используйте -format %A в соответствии с ответом serhiy.h. Из документации:

% Включен канал прозрачности изображения (истина / ложь)

Проверьте, нет ли на изображении прозрачных или полупрозрачных пикселей

Используйте -format %[opaque]. Из документации:

% [opaque] CALCULATED: изображение полностью непрозрачно?


Пример

Для демонстрации давайте создадим изображение a.png, которое имеет альфа-канал, но полностью непрозрачно, и изображение b.png, которое будет таким же, за исключением одного полупрозрачного пикселя:

$ convert rose: PNG32:a.png
$ convert rose: -fill '#0008' -draw "matte 10,10 point" PNG32:b.png

Как и ожидалось, экранирование %A дает True для обоих изображений, поскольку оба имеют альфа-канал:

$ identify -format '%A' a.png
True
$ identify -format '%A' b.png  
True

В то время как escape-последовательность %[opaque] в одном случае дает true, а в другом false из-за одного прозрачного пикселя:

$ identify -format '%[opaque]' a.png
true
$ identify -format '%[opaque]' b.png
false
person smls    schedule 02.01.2016
comment
Спасибо! С таким выводом даже соблазнительно сделать if $(identify -format '%[opaque]' "$file"); then ...; fi - person Camilo Martin; 12.01.2016
comment
Я провел весь день в поисках %[opaque], СПАСИБО - person forresthopkinsa; 24.11.2020

Если вы хотите проверить, действительно ли изображение прозрачное ... (а не только альфа-канал, который может быть неиспользованным)

Используйте эту команду:

convert some_pic.png -verbose info:

(да, в конце команды стоит :)

Это довольно многословно. Ищите список каналов:

(...)
Channel depth:
  red: 16-bit
  green: 16-bit
  blue: 16-bit
Channel statistics:
(...)

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

Но вы также можете получить такой вывод:

(...)
Channel depth:
  red: 16-bit
  green: 16-bit
  blue: 16-bit
  alpha: 1-bit
Channel statistics:
(...)

Здесь есть альфа-канал. Однако это не доказывает, что изображение прозрачное. Он просто говорит, что может быть. В выходных данных команды ищите информацию об альфа-канале:

(...)
  Alpha:
    min: 255 (1)
    max: 255 (1)
    mean: 255 (1)
    standard deviation: 0 (0)
    kurtosis: 0
    skewness: 0
(...)

В этом примере альфа говорит, что изображение непрозрачно: min = max = 1 (1 = непрозрачный, 0 = прозрачный). Таким образом, даже если изображение имеет альфа-канал, пользователь видит непрозрачное изображение.

Вы также можете получить это:

(...)
  Alpha:
    min: 95 (0.372549)
    max: 212 (0.831373)
    mean: 111.187 (0.436028)
    standard deviation: 19.5635 (0.0767196)
    kurtosis: 7.52139
    skewness: -2.80445
(...)

На этот раз min = 0,372549. Это означает, что некоторые пиксели частично прозрачны. mean тоже низкий. Кажется, что большая часть изображения использует прозрачность.

В зависимости от типа проверки, которую вы хотите выполнить (полная непрозрачность, «почти непрозрачность» и т. Д.), Вы должны проверить min, mean и, возможно, standard deviation, если ваш запрос немного сложен.

Примечание: у вас может возникнуть соблазн проверить целочисленные значения для min, mean и других, как я это сделал в первую очередь. В конце концов, с 95 легче иметь дело, чем с 0.372549. Если вы выберете этот маршрут, обратите внимание на глубину альфа-канала. Если это 8 бит, то 255 является максимумом и означает «непрозрачный». Если это 16 бит, то теперь максимум 65535, а 255 означает «почти прозрачный». Лучше проверьте числа с плавающей запятой в круглых скобках, которые всегда находятся в диапазоне от 0 до 1.

Если вы подозреваете, что у многих изображений, которые вы будете обрабатывать, вообще нет альфа-канала, может быть полезно сначала запустить:

identify -format '%[channels]' some_pic.png

Если вываливает:

rgba

есть альфа-канал (a на выходе) и convert следует использовать для проверки min и т. д. Но если его нет, нет необходимости запускать convert. Хотя я не тестировал эти две команды, identify должно быть намного быстрее, чем convert.

person philippe_b    schedule 20.09.2013
comment
Для многих пользователей, людей, которые просто хотят увидеть, нужен ли альфа-канал, достаточно взять строку alpha min и проверить, заканчивается ли она на (1) или нет. - person dash-tom-bang; 19.03.2016
comment
спасибо за развернутый ответ. это на самом деле обеспечивает более глубокое понимание доступа к свойствам изображения и не просто отвечает на вопрос OP, но также расширяет его. - person Denialos; 16.11.2017

identify -format %A some_pic.png

Вернет True, если изображение содержит альфа-канал.

person shapiy    schedule 04.12.2013

Если вы хотите быть уверенным, что альфа-прозрачность действительно используется, единственное решение, которое я вижу, это перебрать все пиксели и получить информацию о цвете, чтобы проверить, прозрачна она или нет. Для больших изображений это будет очень медленно, поэтому в качестве оптимизации вы можете сначала сделать эскиз изображения (скажем, 20x20), а затем проверить пиксели эскиза. Для меня это было хорошим решением.

person Igor Butuc    schedule 24.01.2012

Вот пара функций bash, чтобы проверить, имеет ли png прозрачность или нет, с помощью ImageMagick.

Быстрая проверка, которая просто проверяет наличие альфа-канала:

checkAlphaFast() {
    test $(identify -format %A "$1") == True
}

Медленная проверка, проверяет сами пиксели (даже при наличии альфа-канала):

checkAlphaSlow() {
    test $(identify -format '%[opaque]' "$1") == false
}

Вам следует подумать об использовании быстрой проверки только в том случае, если вы делаете это много, потому что в любом случае это довольно быстро. Спасибо другим людям, которые ответили, из которых я сделал эти функции :)

В качестве бонуса: я не проводил никаких тестов, но он может быть почти таким же быстрым, как быстрый режим, и таким же точным, как медленный режим:

checkAlpha() {
    checkAlphaFast "$1" && checkAlphaSlow "$1"
}

Используйте эти функции следующим образом:

if checkAlpha "$myPNG"; then
    # is transparent
else
    # is opaque
fi

И это даст вам непрозрачность изображения, где 0 полностью прозрачно, а 1 полностью непрозрачно:

checkOpaqueness() {
    if checkAlphaFast "$1"; then
        convert "$1" -verbose info: | grep -A3 Alpha: | tail +4 | head -n1 | sed -r 's/.*\(|\)//g'
    else
        echo 1
    fi
}

И этот выводится как округленный процент, потому что целые числа намного более естественны для bash:

checkPercentage() {
    printf %3.2f $(checkOpaqueness "$1") | tr -d . | sed -r 's/^0?0?//'
}
person Camilo Martin    schedule 12.01.2016