Ошибка при конвертации PDF в PNG в ImageMagick

Ошибка при конвертации PDF в PNG в ImageMagick

Я использую Imagemagick convert для конвертации файла PDF в png следующим образом:

Magick convert -density 300 PointOnLine.pdf -quality 90 PointOnLine.png

Он предупреждает:

convert: profile 'icc': 'RGB ': RGB color space not permitted on grayscale PNG `PointOnLine.png' @ warning/png.c/MagickPNGWarningHandler/1744.

И созданное изображение png полностью черное. Однако конвертация в изображение jpg проходит нормально. В чем проблема? Спасибо.

решение1

Попробуйте добавить -colorspace RGB перед именем выходного файла.

convert -density 300 PointOnLine.pdf -quality 90 -colorspace RGB PointOnLine.png

решение2

Theдокументацияговорит следующее:

PNG RW Portable Network Graphics Требуется libpng-1.0.11 или более поздняя версия, рекомендуется libpng-1.2.5 или более поздняя версия. Спецификация PNG не поддерживает единицы измерения пикселей на дюйм, только пиксели на сантиметр. Чтобы избежать чтения определенного связанного профиля изображения, используйте -define profile:skip=name (например, profile:skip=ICC).

Поэтому попробуйте добавить -define profile:skip=ICC(или skip="*") перед именем выходного файла.

Смотрите также:документация по команде define

решение3

Я использую ImageMagick 7.1.1-8 и столкнулся с той же проблемой:

$ magick example.pdf output.png
magick: profile 'icc': 'RGB ': RGB color space not permitted on grayscale PNG `output.png' @ warning/png.c/MagickPNGWarningHandler/1526.
$ magick -version
Version: ImageMagick 7.1.1-8 Q16-HDRI x86_64 d92cb0e65:20230421 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenMP(4.5) 
Delegates (built-in): bzlib djvu fontconfig freetype heic jbig jng jpeg lcms lqr lzma openexr png raqm tiff webp x xml zlib
Compiler: gcc (7.5)
$ 

В моем случае ImageMagick (использующий Ghostscript) считывает мой входной PDF-файл и создает данные изображения в цветовом пространстве sRGB со встроенным профилем ICC:

$ magick example.pdf -verbose info: | grep "Colorspace:"
  Colorspace: sRGB
$ magick example.pdf -verbose info: | grep -A1 "Profiles:"
  Profiles:
    Profile-icc: 2576 bytes
$ 

При сохранении данных изображения в виде файла PNG ImageMagick автоматически оптимизирует цветовое пространство и сохраняет файл в виде PNG-файла в оттенках серого стип цвета 0:

$ magick output.png -verbose info: | grep "Colorspace:"
  Colorspace: Gray
$ magick output.png -verbose info: | grep "color_type"
    png:IHDR.color_type: 0 (Grayscale)
$ 

Но это такнетудалить встроенный профиль ICC:

$ magick output.png -verbose info: | grep -A1 "Profiles:"
  Profiles:
    Profile-icc: 2576 bytes
$ 

Вот о чем предупреждение: libpng не ожидаетцветПрофиль ICC, встроенный воттенки серогоPNG.

Чтобы избавиться от предупреждения, мы можем либо

  1. сохранить профиль ICC, но скрыть предупреждения в целом,
  2. удалить профиль ICC или
  3. сохраняйте профиль ICC и не сохраняйте как PNG-файл в оттенках серого.

Сохранить профиль ICC, но скрыть предупреждения в целом

Если вы хотите просто скрыть предупреждение, используйте опцию -quiet. В конце концов, это не ошибка, а всего лишь предупреждение:

$ magick example.pdf -quiet output.png
$ 

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

Удалить профиль ICC

Вместо этого вы можете выбрать удаление профиля ICC. Есть несколько способов сделать это. В других ответах упоминается, например, изменение цветового пространства. Это (иногда) работает, потому что ImageMagick автоматически удаляет встроенные профили при изменении цветового пространства:

(void) DeleteImageProfile(image,"icc");
(void) DeleteImageProfile(image,"icm");

Источник:https://github.com/ImageMagick/ImageMagick/blob/7a63f554dc0f986aa3ef2767d041a0f3294decd2/MagickCore/colorspace.c#L1624-L1625

У этого подхода есть два недостатка:

  1. Если ваше изображение уже в цветовом пространстве sRGB и вы используете его -colorspace sRGBдля преобразования в цветовое пространство sRGB, ImageMagick игнорирует оператор, и поэтому профиль не будет удален. Например, мой входной файл PDF создал изображение в цветовом пространстве sRGB, что означает, что -colorspace sRGBне имеет никакого эффекта и не удаляет профиль:

    $ magick example.pdf -colorspace sRGB -verbose info: | grep -A1 "Profiles:"
      Profiles:
        Profile-icc: 2576 bytes
    $ 
    

    И наоборот, то же самое верно, если вы используете -colorspace RGBизображение, которое уже находится в цветовом пространстве RGB. Поэтому, если вы хотите использовать этот метод для удаления профиля ICC, вам придется заранее проверить, находится ли ваше изображение в sRGB или RGB, а затем использовать его -colorspaceсоответственно.

  2. Очевидно, если вы используете -colorspaceдля изменения цветового пространства вашего изображения, цвета вашего изображения могут измениться, что сделает изображение другим. Поэтому после преобразования цветового пространства в другое цветовое пространство для удаления профиля вам следует преобразовать цветовое пространство обратно в исходное цветовое пространство. Таким образом, ваша команда будет использовать оператор -colorspaceдважды. Для моего файла-примера, который является sRGB, я сначала преобразую в RGB, а затем обратно в sRGB:

    $ magick example.pdf -colorspace RGB -colorspace sRGB -verbose info: | grep "Colorspace:"
      Colorspace: sRGB
    $ magick example.pdf -colorspace RGB -colorspace sRGB -verbose info: | grep -A1 "Profiles:"
    $ 
    

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

Альтернативный способ удалить профиль — просто использовать -strip:

$ magick example.pdf -strip -verbose info: | grep -A1 "Profiles:"
$ 

Однако эта опция удаляет не только все профили, но и дополнительные метаданные, что может быть нежелательным поведением. См.https://imagemagick.org/script/command-line-options.php#stripЧтобы получить больше информации.

Чтобы специально удалить профиль ICC из изображения перед сохранением, вы можете использовать +profile icc:

$ magick example.pdf +profile icc -verbose info: | grep -A1 "Profiles:"
$ 

В качестве альтернативы, чтобы изначально не считывать какой-либо профиль ICC из входного файла, можно использовать -define profile:skip=icc:

$ magick -define profile:skip=icc example.pdf -verbose info: | grep -A1 "Profiles:"
$ 

Обратите внимание, что эта настройка влияетчтение, поэтому вам придется поместить его перед входным файлом.

Сохраните профиль ICC и не сохраняйте как PNG в оттенках серого

Наконец, если вы хотите сохранить профиль, вы можете использовать -define png:color-type=для установки желаемого PNGтип цветачтобы избежать автоматического преобразования в оттенки серого и, следовательно, избежать предупреждения. Для моего файла-примера мне может понадобиться "Truecolour with alpha", что является типом цвета 6:

$ magick example.pdf -define png:color-type=6 output.png
$ magick output.png -verbose info: | grep "color_type"
    png:IHDR.color_type: 6 (RGBA)
$

В качестве альтернативы можно использовать, например, PNG32:выходной префикс:

$ magick example.pdf PNG32:output.png
$ magick output.png -verbose info: | grep "color_type"
    png:IHDR.color_type: 6 (RGBA)
$ 

В обоих случаях предупреждение не появляется, но профиль ICC сохраняется:

$ magick output.png -verbose info: | grep -A1 "Profiles:"
  Profiles:
    Profile-icc: 2576 bytes
$ 

Подробнее об этой проблеме можно прочитать на странице обсуждений ImageMagick на GitHub по адресуhttps://github.com/ImageMagick/ImageMagick/discussions/2730иhttps://github.com/ImageMagick/ImageMagick/discussions/6292что обеспечивает отличную поддержку.

Связанный контент