Как создать изображение PNG с color_type=3 и bit_depth=1

Источником является изображение RGBA PNG (color_type=6 и bit_depth=8).

Мне нужно изображение с индексированным цветом и двумя элементами палитры (color_type=3, bit_depth=1).

Я пробовал с ImageMagick, но смог получить только 1-битное изображение в градациях серого (color_type=0, bit_depth=1) или 2-битное индексированное цветное изображение (color_type=3, bit_depth=2), в котором используются только 2 цвета.

По спецификации PNG такое изображение возможно, но как его создать?

Вот изображение, которое я пытаюсь преобразовать:

введите здесь описание изображения

Результат "convert input.png -type palette -depth 1 output.png":

введите здесь описание изображения

Результат "convert input.png -type palette -depth 1 -colors 2 output.png"

введите здесь описание изображения

Оба результата имеют bit_depth=2, но второй использует только 2 цвета из 4 возможных.


person johnfound    schedule 10.01.2015    source источник


Ответы (3)


convert input.png -фон белый -тип палитры -глубина 1 -цвета 2 output.png

работает на меня.

(Почему -depth=1 недостаточно? Понятия не имею.)

Кстати, для проверки такого рода вещей полезен инструмент tweakpng.

Обновление: если изображения имеют прозрачность, вы можете играть безопаснее, удалив ее явно:

convert input.png -фоновый белый -flatten -тип палитры -depth 1 -colors 2 output.png

(Вы можете заменить white на свое усмотрение)

person leonbloy    schedule 10.01.2015
comment
В моих тестах используемые цвета уменьшены до 2, но и разрядность осталась равной 2. Просто используются не все доступные цвета. - person johnfound; 11.01.2015
comment
Пробуя tweakpng, я обнаружил, что 3-й цвет из палитры (индекс 2) используется для фрагмента bKGD. Может быть, нам нужно как-то остановить генерацию этого куска? - person johnfound; 11.01.2015
comment
Я не могу воспроизвести ваш результат, я всегда получаю глубину 1 бит; не могли бы вы опубликовать исходное изображение или сообщить нам его тип (и фрагменты?) - person leonbloy; 11.01.2015
comment
Конечно. Вопрос отредактирован. Я добавил исходное изображение и результаты предложенных команд (также из другого ответа). - person johnfound; 11.01.2015
comment
Странно, я получаю 1 бит глубины с вашим изображением (здесь используется ImageMagick 6.9.0-3 Q16 x64). Я предлагаю сначала удалить прозрачность, например, с -flatten в качестве первой опции. - person leonbloy; 11.01.2015
comment
Мой ImageMagick версии 6.7.7-10; Может быть, это какой-то исправленный баг? Хорошо, я попытаюсь обновить... Индексированные цветные изображения должны поддерживать прозрачность через фрагмент tRNS, поэтому мне нужно преобразование как с прозрачными цветами, так и без них. Например, черный цвет может быть прозрачным. Хорошо, спасибо, пойду попробую обновить. - person johnfound; 11.01.2015
comment
Хорошо, последняя упомянутая команда (с -background black -type palette) работает даже с моей старой версией. -flatten вроде не нужен. Итак, у нас есть ответ. Но, возможно, вам придется внести некоторые изменения в ответ, чтобы объяснить, что именно происходит. :) - person johnfound; 11.01.2015
comment
Если цвет фона является одним из двух цветов переднего плана, то bit_depth=1 достаточно. Если это какой-то другой цвет (например, белый на вашем изображении), то у вас есть всего 3 цвета в палитре, поэтому битовая глубина должна быть 2 или больше. Так как черный является одним из ваших цветов переднего плана, то черный уже есть в палитре, поэтому 2 записей (bit_depth=1) достаточно для хранения палитры, включая цвет фона. - person Glenn Randers-Pehrson; 12.01.2015
comment
@GlennRanders-Pehrson Но в конце я вручную (используя tweakpng) удаляю фрагмент bKGD из изображения. Разве нельзя заставить ImageMagick вообще не использовать его? - person johnfound; 13.01.2015
comment
да. Используйте -define png:exclude-chunk=bKGD - person Glenn Randers-Pehrson; 13.01.2015

Используйте один из следующих 3, упорядоченных от наименьшего до наибольшего количества вспомогательных тегов в выходном файле:

convert -colors 2 -define png:include-chunk=none -verbose input.png output.png

 

convert -colors 2 -define png:exclude-chunk=bkgd -verbose input.png output.png

 

convert -colors 2 -background #000000 -verbose input.png output.png

Корень этой проблемы в том, что ImageMagick по умолчанию помечает изображение белым фоновым цветом (bKGD) PNG. chunk (я бы сказал, без необходимости), а затем добавляет этот цвет в палитру, если его там еще нет, даже если на изображении нет пикселей этого цвета. Ваше конкретное изображение не имеет белого после преобразования в 2-цветное, поэтому ненужный тег цвета фона становится 3-м цветом, и его больше нельзя сохранить как 1-битное индексированное цветное изображение. См. также от автора чат.

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

Первый вариант с -define png:include-chunk=none позволяет избежать проблемы, так как вообще не выводит какие-либо вспомогательные фрагменты PNG (например, bKGD, gAMA, cHRM, tEXt, tIME). Как pngcrush -rem alla. Я бы предпочел это для менее загроможденного файла (без этого IM добавит несколько из них, даже если их не было во входном файле). Примечание. Существует также простая опция -strip, которая следует избегать большинства из них, но начиная с версии 6.9.3 он не отключает bKGD из-за ошибки.

Второй с -define png:exclude-chunk=bkgd удаляет только оскорбительный фрагмент фона.

Третий вариант с -background #000000 сохраняет все вспомогательные фрагменты PNG, включая bKGD, но устанавливает его черным, одним из двух цветов, присутствующих в вашем изображении, поэтому он все еще может быть 1-битным. Отрегулируйте цвет для изображения, в котором нет ни белого, ни черного.

Обратите внимание, что для всего этого я включаю переключатель -verbose. Не слишком многословный; просто переходит от нуля к двум строкам вывода состояния, где вы заметите «2c», если изображение осталось двухцветным, или «3c», если нет. Он также сообщит вам, было ли уменьшение палитры с потерями или нет. Он также выводит «8-битный sRGB» для большинства изображений, даже для изображений с палитрой с менее чем 8 битами на пиксель; это не ошибка, как в вашем комментарии к другому ответу @johnfound, это относится не к битам на пиксель, а к компоненту битов на цвет. Он может быть более 8-битным для (редких) изображений с глубоким цветом.

person WinTakeAll    schedule 28.03.2016

Я думаю, что вам нужна команда:

convert input.png -type palette -depth 1 output.png

Если нет, опубликуйте свое входное изображение и скажите, как/где вы находите поля color_type и bit_depth, на которые вы ссылаетесь.

Exiftool говорит мне следующее:

ExifTool Version Number         : 9.76
File Name                       : output.png
Directory                       : .
File Size                       : 2.3 kB
File Modification Date/Time     : 2015:01:10 19:20:33+00:00
File Access Date/Time           : 2015:01:10 19:21:46+00:00
File Inode Change Date/Time     : 2015:01:10 19:20:33+00:00
File Permissions                : rw-r--r--
File Type                       : PNG
MIME Type                       : image/png
Image Width                     : 640
Image Height                    : 427
Bit Depth                       : 1
Color Type                      : Grayscale
Compression                     : Deflate/Inflate
Filter                          : Adaptive
Interlace                       : Noninterlaced
Gamma                           : 2.2
Background Color                : 1
Datecreate                      : 2015-01-10T10:21:30+00:00
Datemodify                      : 2015-01-10T10:21:30+00:00
Image Size                      : 640x427

ImageMagick identify говорит мне следующее:

Image: output.png
  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: PseudoClass
  Geometry: 640x427+0+0
  Units: Undefined
  Type: Bilevel
  Base type: Bilevel
  Endianess: Undefined
  Colorspace: Gray
  Depth: 8/1-bit
  Channel depth:
    gray: 1-bit
  Channel statistics:
    Pixels: 273280
    Gray:
      min: 0 (0)
      max: 255 (1)
      mean: 1.90168 (0.00745755)
      standard deviation: 21.9388 (0.0860345)
      kurtosis: 129.1
      skewness: 11.4499
  Colors: 2
  Histogram:
    271242: (  0,  0,  0) #000000 gray(0)
      2038: (255,255,255) #FFFFFF gray(255)
  Colormap entries: 2
  Colormap:
         0: (  0,  0,  0) #000000 gray(0)
         1: (255,255,255) #FFFFFF gray(255)
  Rendering intent: Undefined
  Gamma: 0.45455
  Background color: gray(255)
  Border color: gray(223)
  Matte color: gray(189)
  Transparent color: gray(0)
  Interlace: None
  Intensity: Undefined
  Compose: Over
  Page geometry: 640x427+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: Zip
  Orientation: Undefined
  Properties:
    date:create: 2015-01-10T19:20:33+00:00
    date:modify: 2015-01-10T19:20:33+00:00
    png:bKGD: chunk was found (see Background color, above)
    png:gAMA: gamma=0.45455 (See Gamma, above)
    png:IHDR.bit-depth-orig: 1
    png:IHDR.bit_depth: 1
    png:IHDR.color-type-orig: 0
    png:IHDR.color_type: 0 (Grayscale)
    png:IHDR.interlace_method: 0 (Not interlaced)
    png:IHDR.width,height: 640, 427
    png:text: 2 tEXt/zTXt/iTXt chunks were found
    signature: 3e08d7fea7bc7aeb0659ac2e2696084083d35ce30b0e3075dc561ad94259eaec
  Artifacts:
    filename: output.png
    verbose: true
  Tainted: True
  Filesize: 2.33KB
  Number pixels: 273K
  Pixels per second: 27.33MB
  User time: 0.000u
  Elapsed time: 0:01.009
  Version: ImageMagick 6.8.9-8 Q16 x86_64 2014-11-10 http://www.imagemagick.org
person Mark Setchell    schedule 10.01.2015
comment
К сожалению, приведенная выше команда генерирует изображение с типом цвета 3, но глубиной цвета 2; Я проверяю значения полей, непосредственно анализируя изображения — это тестовые изображения для реализации моей библиотеки декодирования PNG. Эти значения правильные, потому что программа умеет их декодировать и отображать. Кстати, на тех же изображениях идентификация -verbose дает неправильное значение 8 для битовой глубины - вероятно, ошибка. - person johnfound; 10.01.2015