Я только что столкнулся с неожиданным поведением в ImageMagick, которое, надеюсь, мне кто-нибудь объяснит.
Номера версий
$ convert --version
Version: ImageMagick 6.7.7-10 2013-02-25 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC
Features: OpenMP
Работает на Linux Mint 15 Olivia (на основе Ubuntu 13.04 «Raring Ringtail»).
Резюме
Выполняя ту же операцию с двумя изображениями, которые должны быть очень похожими, за исключением того, что одно из них — GIF, а другое — JPEG, результирующий результат будет совершенно другим. GIF получается черным, JPEG — белым.
Чтобы воспроизвести:
- Перейдите по адресу http://karenswhimsy.com/public-domain-images/animal-silhouettes/animal-silhouettes-1.shtm и загрузите силуэт слона как
elephant.jpg
- Загрузите http://www.arthursclipart.org/silhouettes/animals/DUCK1.gif как
DUCK1.gif
convert elephant.jpg -negate -alpha shape output-elephant.png
convert DUCK1.gif -negate -alpha shape output-duck.png
- Сравните изображения
output-elephant.png
иoutput-duck.png
Кто-нибудь может объяснить, почему эти два выходных изображения отличаются? Почему утка GIF после конвертации становится черной, а слон JPEG после конвертации становится белой?
Многословное объяснение
Ситуация такова: я хочу взять несколько черно-белых изображений, сделать фон прозрачным и покрасить передний план в разные цвета. Например, начиная с силуэта слона по адресу http://karenswhimsy.com/public-domain-images/animal-silhouettes/images/animal-silhouettes-1.jpg (я сохранил изображение как elephant.jpg
), я хочу создать .png с прозрачным фоном и слон зеленого, красного, желтого или любого другого цвета, который я хочу.
Команда, которую я использую для этого:
convert elephant.jpg -negate -alpha shape +level-colors ,green green-elephant.png
Это делает именно то, что я хочу. Сначала он инвертирует изображение, чтобы фон был черным, а слон белым, потому что -alpha shape
ожидает альфа-маску, где черный = полностью прозрачный, а белый = полностью непрозрачный. Затем -alpha shape
делает свое волшебство и создает белого слона на прозрачном фоне. Затем вступает в действие +level-colors ,green
, преобразовывая черно-белые градиенты в два цвета, указанные в качестве параметров для +level-colors
; здесь первый цвет опущен, поэтому он остается черным, а второй цвет — это то, во что превращается белый. Это дает зеленого слона с гладкими границами — именно тот результат, который мне нужен — и я им вполне доволен.
Затем я попытался запустить ту же команду для одного из изображений с http://www.arthursclipart.org/silhouettes/animals.htm (я использовал DUCK1.gif
). Источник ввода тот же — черный силуэт на белом фоне — поэтому я ожидал того же результата — зеленая утка на прозрачном фоне. Но это не сработало. Небольшое исследование показало мне, что -alpha shape
ведет себя по-другому. В случае со слоном в формате JPEG она создавала белого слона на прозрачном фоне, а в случае с уткой в формате GIF та же самая команда создавала черную утку на прозрачном фоне. Другими словами, -alpha shape
инвертировал результат с источником изображения GIF, но не с источником изображения JPEG. Поэтому, чтобы правильно раскрасить животное, мне нужно было переписать +level-colors
параметров, чтобы поставить «зеленый» перед запятой, а не после.
Настроить мой сценарий не проблема, но я хотел бы понять, почему это происходит, и пока я ничего не знаю. Может ли кто-нибудь объяснить мне, почему ImageMagick так по-разному обрабатывает GIF-файлы и JPEG-файлы в операции -alpha shape
?