LINUX.ORG.RU

Сменить палитру в 8-битном PNG

 , , растровые изображения


0

1

Что умеет менять палитру (colourmap) в рисунках с индексированными цветами? Стоят 2 задачи:

1. Выдать в понятном текстовом виде таблицу «Номер — уровни R, G, B и альфа» для палитры 8-битного PNG.

2. Взять 8-битный PNG с произвольной палитрой и преобразовать в 8-битный PNG в котором цвета в палитре находятся в заданном «эталонном» порядке. Известно, что в эталонной палитре все цвета исходного файла присутствуют.

Чем это можно сделать?

GIMP, как выяснилось, глючит и теряет цвета.

Krita не умеет работать с индексированными цветами.

То, что NetPBM называет «палитрой», оказалось списком используемых в данном файле цветов в произвольном порядке.

Аналогично с выдачей identify -verbose из пакета ImageMagic, но я ещё не закончил изучать доки.

Про GraphicMagic утверждают, что он тасует цвета в случайном порядке. До него я тоже ещё не добрался.

В XV, XPaint, Tuxpaint, Pinta, MyPaint ничего похожего на загрузку произвольной палитры я не нашёл. Плохо искал?

P.S. MyPaint вдобавок при экспорте обрезает пустое пространство с нижнего краю.

Подытог:

Обходной путь:

  • загрузить файл в GIMP,
  • экспортировать палитру (например, в GPL),
  • руками добавить в неё правильный нулевой цвет,
  • импортировать палитру,
  • применить её к испорченному рисунку,
  • экспортировать в PNG.

Если стартовый файл без повреждений, ничего не теряется.

Дополнение: В документации на библиотеку Питона Pillow (бывшая PIL) описывается функция Image.remap_palette(), которая именно так заменяет индексы в палитре: https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.... Если так, то программа запишется строк в 6.

Дополнение 2: Можно восстановить потерявшую 1 цвет палитру средствами самого Гимпа. В редакторе палитры добавить в конец 256-й цвет, сохранить, затем в списке палитр сделать из контекстного меню «Offset Palette» на 1. Но делать так при каждом открытии 8-битного PNG с альфа-каналом неприемлемо трудоёмко.

★★★★★

Последнее исправление: question4 (всего исправлений: 5)

1) Сохранить в gimp-e в формате ppm, прочесть его самодельной Сишной прогой (это массив троек байт), напечатать РГБ. Или сохранить в ХРМ, сверху палитра. 2) Прочесть ПНГ сишной прогой, с зашитой палитрой, для каждого пикселя найти ближайший цвет. (яркость болше весит, чем цветность)

anonymous
()
Ответ на: комментарий от anonymous

1) Сохранить в gimp-e в формате ppm,

Нельзя, Гимп теряет белый цвет.

прочесть его самодельной Сишной прогой (это массив троек байт), напечатать РГБ. Или сохранить в ХРМ, сверху палитра.

Важен порядок цветов в палитре. В PNM эта информация отсутствует.

2) Прочесть ПНГ сишной прогой, с зашитой палитрой, для каждого пикселя найти ближайший цвет. (яркость болше весит, чем цветность)

Искать ближайший не нужно, расхождений быть не должно :)

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

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

Нельзя, Гимп теряет белый цвет.

Как так? РРМ (не PNM) - это массив пикселей, куда денется белый элемент?

Готового не встречал.

anonymous
()
Ответ на: комментарий от anonymous

Нельзя, Гимп теряет белый цвет.

Как так? РРМ (не PNM) - это массив пикселей, куда денется белый элемент?

Вопрос возник в связи с попытками локализовать вот этот баг: https://bugzilla.gnome.org/show_bug.cgi?id=791531

Когда Гимп импортирует файл, он убирает цвет номер 0 и перенумеровывает цвета 1-255 в 0-254. Когда он экспортирует этот же файл, он восстанавливает старый цвет номер 0, затирая тот, который был 1 в исходном, вместо того, чтобы перенумеровать обратно. В приаттаченых примерах терялся белый (точнее, #FCFCFC).

question4 ★★★★★
() автор топика
Последнее исправление: question4 (всего исправлений: 1)

да шо там менять-то? любым hex-редактором можно, почитай спецификацию формата. если надо визуально, то глянь древний mtpaint, он как раз для такого.

anonymous
()
Ответ на: комментарий от anonymous

в hex-редакторе находишь буквы PLTE, за ними следуют трёхбайтовые значения rgb подряд для каждого цвета палитры. альфа лежит отдельно, в чанке tRNS, как последовательность однобайтовых значений для соответствующего цвета палитры. первый байт из tRNS - это альфа для первых трёх байт из PLTE; второй байт из tRNS - альфа для второго цвета из палитры... и т.д.

пруф

anonymous
()
Ответ на: комментарий от anonymous

да шо там менять-то? любым hex-редактором можно, почитай спецификацию формата.

Ага, только нужно научиться распаковывать в уме чанки, сжатые deflate :) А затем прибавить к каждому байту 1 и сжать обратно.

если надо визуально, то глянь древний mtpaint, он как раз для такого.

Ебилда нет, но попробую, спасибо.

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

нужно научиться распаковывать в уме чанки, сжатые deflate

изи же

anonymous
()
Ответ на: комментарий от anonymous

в hex-редакторе находишь буквы PLTE, за ними следуют трёхбайтовые значения rgb подряд для каждого цвета палитры. альфа лежит отдельно, в чанке tRNS, как последовательность однобайтовых значений для соответствующего цвета палитры. первый байт из tRNS - это альфа для первых трёх байт из PLTE; второй байт из tRNS - альфа для второго цвета из палитры... и т.д.

Считать 256 цветов в уме? Проще написать программу. А сперва стоит проверить, не написал ли кто-либо её до меня. Для этого и создал тему.

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

не знаю

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

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.