Понимание консольной утилитой ImageMagick-Convert и перевод в Ruby RMagick


Мне не удается перевести следующий код PHP / ImageMagick в Ruby RMagick (чтобы сделать его более управляемым для будущих пользователей и понять, что он на самом деле делает):

$output = array();
$returnValue = 0;
$pngFiles = $myDir->find("/.png$/i");
foreach($pngFiles as $pngFile) {
   $cmd = 'convert '.$pngFile->path.' -resize 1x1 -alpha on -channel o -format "%[fx:u.a]" info:'
   exec($cmd, $output, $returnValue);
   if($output[0] != 1) {
      logMessage("PNG file contains some alpha transparency and will not be modified");
   }
}

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

Например: почему это $output[0] != 1 иногда ... true на PNGs в $myDir, но Rmagick's Image.alpha? есть всегда true на PNGs в $myDir? Я что-то упустил?

Я думаю, что лучший способ вернуть меня в нужное русло был бы, если бы кто-нибудь мог объяснить мне, что именно делает команда convert (включая выражение %[fx:u.a]).

Update : тем временем я написал сценарий, для которого мне нужна была эта информация. Вы можете проверить это на Github, Если это вам поможет.

5 4

5 ответов:

Код проверяет, содержит ли конкретное изображение прозрачность.

-format '%[fx:u.a]' info:

Это дает команду image magick проверить первое изображение u, альфа-канал этого a и вывести информацию о нем, он вернет 0, если верхний левый пиксель прозрачен и ненулевой, если нет, я думаю. Именно поэтому размер изображения изменяется до 1x1, так что требуется только один пиксель. -channel o - это канал непрозрачности.

Таким образом, код на английском языке будет гласить: цикл во всех файлах PNG смотрите только на альфа-канал (непрозрачность), измените размер до одного пикселя и посмотрите, прозрачен ли он. Отсюда и Эхо-сообщение.

К сожалению, я не знаю Ruby или RMagick, но быстрый взгляд на API, кажется, предлагает использовать image.channel(AlphaChannel) для получения Альфа-канала (AlphaChannel является значением ChannelType, не уверен, Нужно ли указывать ChannelType.AlphaChannel), затем следовать с .resize(1,1), чтобы уменьшить размер, и закончить либо с .pixel_color(0,0), либо с .get_pixels(0,0,1,1), чтобы вернуть объект Pixel (get_pixels() возвращает массив), который, как я полагаю, имеет атрибут opacity. Однако команда channel() изменяет значения RGB на значение выбранного канала, и я не уверен, что она сохраняет канал непрозрачности, поэтому вам, возможно, просто нужно посмотреть на red forinstance или полностью опустить вызов .channel(), хотя я не знаю, нарушит ли это результат.

Возможно, если Ruby поддерживает достойные подходы функционального программирования.

image.channel(AlphaChannel).resize(1,1).pixel_color(0,0).red

Или это, если pixel_color() не возвращает непрозрачность для некоторых причина

image.channel(AlphaChannel).resize(1,1).get_pixels(0,0,1,1)[0].red

Без channel() вызовов это было бы:

image.resize(1,1).pixel_color(0,0).opacity

Или

image.resize(1,1).get_pixels(0,0,1,1)[0].opacity
Опять же, мой Рубин не существует, так что вам, возможно, придется много их переставлять, но примитивы есть.

Ссылки

  1. Документация RMagick
  2. ImageMagick ' fx ' escapes
  3. ImageMagick-параметры канала

Для тех, кто все еще ищет решение этой проблемы, есть способ сделать это в ruby, используя rmagick драгоценный камень, описанный здесь https://stackoverflow.com/a/41282162/1975112

Php-код, который вы показываете (который на самом деле просто отправляет работу для преобразования в оболочке), не проверяет, есть ли у изображений Альфа-каналы, он просто берет любой файл и включает его. Если бы он уже был один, то не было бы никакого изменения файла, но convert не просят принять какое-либо решение на основе статуса, просто идите вперед и добавьте канал.

Почему вы не скопировали только команду и не вызвали ее с помощью system ?

Драгоценные камни не требуются ... никаких вопросов, код должен выглядеть почти так же.

EDIT: RMagic только обертывает imagemagic, так зачем беспокоиться о rmagic, если у вас уже есть командная строка imagmagic.

Я никогда не кодировал ни одной строки Ruby, но вот частичный ремейк PHP-скрипта:

require 'find'

pngFiles = Dir.glob("*.png")

Find.find('./') do |f|
  if system 'convert ' + f + ' -resize 1x1 -alpha on -channel o -format "%[fx:u.a]" info' do
    print "PNG file contains some alpha transparency and will not be modified"
Я думаю, что единственное, что вам нужно проверить, это просто альфа-канал, а не все эти сложные вещи. Смотрите на этой странице для получения дополнительной информации: http://www.imagemagick.org/script/escape.php у него есть оператор %A, и он выводит что-то о альфа-канале.