Проблема с медленной работой команды ImageMagick

Я использую ImageMagick для некоторой обработки изображений в моем веб-приложении (используя Java в качестве бэкэнда в ОС Ubuntu), чтобы идентифицировать цвета CMYK из изображений.

Исходное изображение:

Проблема с медленной работой команды ImageMagick

Процедура для всего изображения приведена ниже:

Сначала я разделяю четыре изображения в оттенках серого CMYK:

convert IMG_1732.jpg -colorspace CMYK -negate -separate IMG_1732-sep.jpg

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

Изображение 1:

Проблема с медленной работой команды ImageMagick

Изображение 2:

Проблема с медленной работой команды ImageMagick

Изображение 3:

Проблема с медленной работой команды ImageMagick

Изображение 4:

Проблема с медленной работой команды ImageMagick

Затем я выполняю следующие команды, чтобы преобразовать каждую из оттенков серого в цветное изображение C, M, Y, K:

convert IMG_1732-sep-0.jpg -channel C -combine IMG_1732-sep-00.jpg

Результат 1:

Проблема с медленной работой команды ImageMagick

convert IMG_1732-sep-1.jpg -channel M -combine IMG_1732-sep-11.jpg

Результат 2:

Проблема с медленной работой команды ImageMagick

convert IMG_1732-sep-2.jpg -channel Y -combine IMG_1732-sep-22.jpg

Результат 3:

Проблема с медленной работой команды ImageMagick

convert IMG_1732-sep-3.jpg -channel K -combine IMG_1732-sep-33.jpg

Результат 4:

Проблема с медленной работой команды ImageMagick

Проблема в том, что это занимает слишком много времени, размер изображения составляет около 2–3 МБ. Кроме того, потребляет больше оперативной памяти и процессора.

  • Как мне его оптимизировать? Есть ли другой вариант в ImageMagick или Любым другим путем?
  • Как я могу узнать процент CYAN, доступный в исходном изображении? Такой же, как пурпурный, желтый и черный? Является ли это возможным?

Я понимаю, что первая команда преобразует изображение в CMYK, инвертирует каналы и разделяет их на 4 отдельных файла JPG. Я понятия не имею, что пытаются сделать следующие 4 команды? Вы говорите, что хотите "найти CMYK в каждом", но что это значит? В отдельном файле, содержащем C, не будет ни MY, ни K. Каким будет ответ на ваш вопрос - ожидаете ли вы изображения чего-либо? четыре отдельных изображения чего-то? средства каких изображений? Мне это очень непонятно!

Mark Setchell 29.08.2018 14:58
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
1
104
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я согласен с Марком Сетчеллом. Ваш вопрос не очень ясен.

Если вы хотите найти цветовой эквивалент CMYK для любого пикселя на входе RGB, вы можете сделать следующее, например, для пикселя (10,10). Здесь я использую специальную розу ImageMagick: image. Но вы можете поставить любое реальное изображение (image.suffix) вместо rose :. Для реальных изображений не включайте последнее двоеточие.

convert rose: -colorspace CMYK -format "%[pixel:u.p{10,10}]\n" info:

cmyk(0,28,53,183)


Если вы хотите, чтобы все изображение или его часть отображали значения CMYK, используйте txt: output. Например, вот верхняя левая секция 2x2 розы: изображение.

convert rose:[2x2+0+0] -colorspace CMYK txt:

# ImageMagick pixel enumeration: 2,2,65535,cmyk
0,0: (0,1365,4096,53199)  #000510CF  cmyk(0,5,16,207)
1,0: (0,2621,5243,52685)  #000A14CD  cmyk(0,10,20,205)
0,1: (0,1394,4183,53456)  #000510D0  cmyk(0,5,16,208)
1,1: (0,1365,4096,53199)  #000510CF  cmyk(0,5,16,207)

Если вы пытаетесь выделить каждый канал C, M, Y, K как отдельные изображения, ваша первая команда сделает именно это:

convert IMG_1732.jpg -colorspace CMYK -negate -separate IMG_1732-sep.jpg


Каждое результирующее изображение, IMG_1732-sep-0.jpg, IMG_1732-sep-1.jpg, IMG_1732-sep-2.jpg, IMG_1732-sep-3.jpg, представляет соответствующий инвертированный (инвертированный) канал C, M, Y, K . Нет необходимости в дальнейшей обработке. ImageMagick identify скажет, что они полутоновые, но значения представляют инвертированные C, M, Y, K для каждого изображения.

Обратите внимание, что любое одноканальное изображение будет отображаться в ImageMagick 6 как 3 идентичных канала. В ImageMagick 7 это отдельные каналы в градациях серого.

Также обратите внимание, что -combine потребуется 3 или 4 входных изображения для обратного объединения в RGB или CMYK. Поэтому я не уверен, что пытаются делать другие ваши команды.

Обновленный вопрос. пожалуйста, проверьте

Darshan Patel 30.08.2018 07:50

Я не уверен в этом, но поработал и хотел им поделиться. Я или один из моих приятелей по StackOverflow могли бы придумать что-то получше, когда мы лучше поймем, поэтому я покажу, что у меня есть на данный момент.

Медлительность, вероятно, происходит из-за необходимости запускать 5 процессов и необходимости читать изображения JPEG и декодировать их 5 раз, поэтому я хочу использовать один процесс и делать все за один раз.

Вот что у меня есть:

convert image.jpg -colorspace cmyk -separate -write MPR:orig                                             \
   +delete -colorspace gray -threshold 101% -write MPR:blackx3 -delete 0,1,2                             \
   \( MPR:orig -delete 1,2,3 MPR:blackx3           -set colorspace CMYK -combine -write C.jpg +delete \) \
   \( MPR:orig -delete 0,2,3 MPR:blackx3 -swap 0,1 -set colorspace CMYK -combine -write M.jpg +delete \) \
   \( MPR:orig -delete 0,1,3 MPR:blackx3 -swap 0,2 -set colorspace CMYK -combine -write Y.jpg +delete \) \
      MPR:orig -delete 0,1,2 K.jpg

Я уверен, что это немного обескураживает, поэтому я буду объяснять каждую строчку за раз ...

Линия 1: Загрузите исходное изображение, преобразуйте его в цветовое пространство CMYK и разделите на 4 отдельных изображения, одно с C, одно с M, одно с Y и одно с K. Сохраните все 4 из этих изображений в кучу ОЗУ под названием "orig".

Строка 2: Удалите последний канал в стеке, которым был K, оставив C, M и Y. Сделайте все эти 3 изображения полностью черными и сохраните в кучу памяти с именем "blackx3", чтобы у меня были три пустых черных канала на будущее.

Строка 3: Перезагрузите CMYK из ОЗУ, удалите MYK, оставив C, затем загрузите 3 пустых черных канала. Теперь у нас в стеке C, Black, Black, Black. Сообщите IM, что 4 изображения в нашем стеке являются каналами CMYK, объедините их и запишите как "C.jpg". Убирайся.

Строка 4: Перезагрузите CMYK из ОЗУ, удалите CYK, оставив M, затем загрузите 3 пустых черных канала. Теперь у нас в стеке M, Black, Black, Black. Поменять местами на Черный, M, Черный, Черный. Сообщите IM, что 4 изображения в нашем стеке являются каналами CMYK, объедините их и запишите как "M.jpg". Убирайся.

Строка 5: Перезагрузите CMYK из ОЗУ, удалите CMK, оставив Y, затем загрузите 3 пустых черных канала. Теперь у нас в стеке Y, Black, Black, Black. Поменять местами порядок на Черный, Черный, Y, Черный. Сообщите IM, что 4 изображения в нашем стеке являются каналами CMYK, объедините их и запишите как "Y.jpg". Убирайся.

Строка 6: Загрузить CMYK из ОЗУ. Удалите CMY, оставив черный, сохраните как "K.jpg".

Это дает следующее:

Спасибо, Марк, это действительно улучшает производительность. Однако K.jpg дает на выходе и другие цвета. Остальные тройки верны

Darshan Patel 30.08.2018 13:17

Я добавил полученные результаты. На мой взгляд, они выглядят как правильные цветоделения для входного изображения, хотя я не являюсь экспертом в технологии печати. Возможно, вы могли бы щелкнуть edit под своим вопросом и вставить что-нибудь другое. Кроме того, какая у вас версия ImageMagick? Я использую v7.0.8.

Mark Setchell 30.08.2018 13:55

Да, ваши изображения верны. Я использую ImageMagick 6.7.7-10

Darshan Patel 30.08.2018 14:21
Ответ принят как подходящий

Невозможно получить цветное изображение для вашего номера 4, если это был канал, отделенный от CMYK. Все отдельные каналы будут в оттенках серого. Также я не могу воспроизвести ваши точные цвета. Значит, либо изображение другое, либо изменено, либо вы не сообщили нам все этапы обработки.

Подобно команде Марка Сетчелла, я могу написать вашу команду в одной командной строке и получить время обработки около 0,63 секунды.

time convert image.jpg -colorspace cmyk -negate -separate \
\( -clone 0 -channel C -combine +write C.jpg \) \
\( -clone 1 -channel M -combine +write M.jpg \) \
\( -clone 2 -channel Y -combine +write Y.jpg \) \
\( -clone 3 -channel K -combine +write K.jpg \) \
null:

0.626s


C.jpg

M.jpg

Y.jpg

K.jpg

Если вам нужны файлы меньшего размера, добавьте -quality XX к каждой из команд в скобках непосредственно перед + write. Или найдите инструмент оптимизатора JPG для последующей обработки каждого полученного изображения. Imagemagick использует libjpeg, который может быть не самым эффективным компрессором. Я проверил, и ваш ввод, и все мои выходные результаты используют качество 95.

Если я включу -normalize для увеличения контраста, я смогу приблизиться к вашим результатам, но время обработки увеличится примерно до 0,83 секунды.

convert image.jpg -colorspace cmyk -negate -separate -normalize \
\( -clone 0 -channel C -combine +write C.jpg \) \
\( -clone 1 -channel M -combine +write M.jpg \) \
\( -clone 2 -channel Y -combine +write Y.jpg \) \
\( -clone 3 -channel K -combine +write K.jpg \) \
null:

Как я могу узнать процент CYAN, доступный в исходном изображении? Такой же, как пурпурный, желтый и черный?

convert image.jpg -colorspace CMYK -format "%[fx:mean.c], %[fx:mean.m], %[fx:mean.y], %[fx:mean.k]\n" info: 

Выход : 0,0606194, 0,0598201, 0,0300933, 0,0748128

Эти значения представляют собой дроби в диапазоне от 0 до 1. Для процентов умножьте каждое среднее значение на 100. Обратите внимание, что двоеточие в конце является обязательным.

Круто - так лучше. Я знал, что не думаю правильно :-)

Mark Setchell 30.08.2018 19:58

Есть ли способ узнать процентное содержание C, M, Y, K в сгенерированных четырех изображениях?

Darshan Patel 31.08.2018 11:31

Вы можете просто получить среднее значение изображения, я полагаю, с помощью convert C.jpg -format "%[fx:100*mean] info:. Или из вашего оригинального образа convert input.jpg -colorspace CMYK -format "%[fx:mean.c], %[fx:mean.m], %[fx:mean.y], %[fx:mean.k]" info:. Вы можете добавить к команде свой -negate, если хотите, чтобы результаты совпадали с вашим отрицательным результирующим C.jpg и т. д.

fmw42 31.08.2018 18:49

Я имею в виду, должен ли я знать из любого образа, какой процент CYAN доступен в исходном образе? Такой же, как пурпурный, желтый и черный? Ваша команда сгенерирует новое изображение.

Darshan Patel 03.09.2018 06:53

Эта команда не должна создавать новый образ. Пишет только инфу:. Обратите внимание, что двоеточие в конце необходимо. convert logo: -colorspace CMYK -format "%[fx:mean.c], %[fx:mean.m], %[fx:mean.y], %[fx:mean.k]\n" info: возвращает только 0.0606194, 0.0598201, 0.0300933, 0.0748128 на моем Mac OSX Sierra с IM 6.9.10.11 Q16. Эти значения представляют собой дроби в диапазоне от 0 до 1. Если вам нужны проценты, умножьте каждое среднее на 100. Какова ваша точная версия и платформа ImageMagick?

fmw42 03.09.2018 07:52

Другие вопросы по теме