Как сохранить метаданные игры в файле .png?

208

Spore позволяет создавать существа, созданные игроком, путем экспорта .pngфайла. Это .pngфотография существа, но если она импортирована в игру, информация о существе (например, текстуры, размер и форма) также приходит с ним.

Как я могу реализовать такую ​​функцию?

ibrabeicker
источник
5
Должен иметь гораздо более высокий балл, это очень интересный вопрос.
Пьер Арло
3
Альфа-канал может быть частично оскорблен для этого ...
Тобиас Кинцлер,
3
Возможно использование: stackoverflow.com/questions/9542359/…
логическое устройство
1
Я думаю, что лучше хранить эти данные в другом файле. В этом файле должно быть имя файла текстуры, связанного с сущностью, для которой вы хотите сохранить данные. Во-первых, ради простоты (формат png для графики - «Переносная сетевая графика»), во-вторых: рассмотрим ситуацию, когда вы хотите сохранить больше изображений с сущностью, вы можете просто добавить ссылки на нее из этого пользовательского файла. Возможно, у вас возникнут проблемы с хранением разных изображений (разного размера, разной глубины и т. Д.) В одном PNG.
luke1985
3
Альфа-канал широко упоминался, и, конечно, PNG в любом случае поддерживают метаданные, но я просто подумал, что поделюсь методикой, которую я использовал - пошагово проходя слева направо, сверху вниз и через каналы в фиксированном порядке. и округление значений до шансов или четностей - не имеет значения, если это вверх или вниз. Изменение 1 в ЛЮБОМ из каналов не делает заметной разницы, и в изображении 256x256 (конечно, с 4 битами на пиксель) вы можете хранить впечатляющие 32 КБ данных. Если вам нужно еще больше, вы можете вместо этого округлить до% 4 - слишком много, и это начинает выглядеть как старый ум GIF ..
Octopoid

Ответы:

56

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

Несколько инструментов кодируют эти данные для вас, поиск Google выявляет, по крайней мере, это и это .

PNG имеет байтовую подпись $89в начале, поэтому возможно, что информация была вставлена ​​после самой структуры PNG и просто проанализирована игрой SPORE.

Однако дальнейшие исследования, проведенные другими ответами и поиском в Google, показывают, что Spore фактически использовала только версию Stegongraphy, чтобы скрыть информацию в альфа-битах. Имея это в виду, мы можем исключить возможность добавления данных или метаданных.

Следует отметить, что метаданные все еще являются очень жизнеспособным выбором, если данные анализируются локально. Если эта информация может быть передана через Интернет или перекодирована, экспорт не гарантирует сохранение всей вашей информации. Когда используются пиксельные данные, они могут без потерь переживать преобразования без потерь.

Вон Хилтс
источник
3
Насколько я знаю, спора хранит метаданные внутри альфа-канала PNG.
Тара
28
Зачем использовать альфа-канал или стеганографию, если PNG поддерживает произвольные фрагменты метаданных?
Рассел Борогове
8
«PNG имеет байтовую подпись« 89 »в начале, поэтому весьма вероятно, что информация была вставлена ​​до или после самой структуры PNG и просто проанализирована игрой SPORE». Если бы это было так, то это не больше не будет файлом PNG. Т.е. обычные зрители изображения не смогут его отобразить.
svick
3
@RussellBorogove одна довольно веская причина: если PNG декодируется / кодируется чем-то кроме Spore, произвольные фрагменты метаданных с большей вероятностью будут проигнорированы или потеряны, чем фактические данные изображения. Кодирование данных на изображении повышает вероятность того, что, если вы их видите, вы можете загрузить их .
Тим С.
@svick На самом деле, я играл с файлом, который был действительным PNG и RAR. Заголовок RAR начался после PNG, и экстракторы RAR были в порядке. Это может нормально работать и в другом направлении.
корчи
153

Формат PNG поддерживает более или менее произвольные метаданные. Стандарт PNG определяет файл PNG, по существу, последовательность фрагментов, некоторые из которых являются обязательными (и содержат данные изображения). Другие, однако, не являются обязательными. Например, есть блок для хранения гамма-информации или данных гистограммы.

В частности, есть tEXtблок, который можно использовать для хранения произвольных пар ключ / значение. Это может быть использовано для отправки произвольных данных любого типа, которые вы хотите, при условии, что вы можете представить эти данные в виде текста (что весьма вероятно).

Вам понадобится библиотека PNG, которая позволит вам получать доступ к этим дополнительным фрагментам (например, справочная библиотека ) и манипулировать ими , или вам нужно будет написать ее самостоятельно. Тогда нужно просто выбрать способ кодирования данных в виде пар ключ / значение. Я бы предложил следующее:

  • выбирайте имена ключей с префиксом имени вашего проекта или кодового имени как способ создания грубой системы «пространства имен» и избегайте потенциальных конфликтов с использованием данных другими приложениями
  • не пытайтесь хранить фактические текстуры таким образом, храните ссылки на те текстуры, которые указывают в базе данных ресурсов вашей игры
  • такие данные, как размер существа или объекта, вес и так далее - простые скаляры, в основном - могут быть тривиально сохранены

В интересах более полного ответа я также укажу, что существует другой подход (ранее задокументированный в ответах @Vaughn и @ Alexis): кодировать дополнительные данные, которые вы хотите, непосредственно в пикселях изображения, распределяя их по младшие биты цветовых каналов. Этот подход не требует использования дополнительных метаданных, что означает, что вы можете реализовать их полностью, не полагаясь на них или не беспокоясь о том, что внешние программы неправильно обрабатывают эти метаданные. Он также имеет очень высокий «крутой» коэффициент, и поскольку вы используете только младшие биты, изображение все равно будет выглядеть правильно для человеческого глаза. Однако это означает, что размер вашего изображения является основным определяющим фактором для объема данных, которые вы можете хранить; если вам нужно больше памяти, вам нужно выделить больше пикселей для изображения.

Как уже отмечали другие, этот процесс известен как стеганография .

Джош
источник
3
Можно просто отправить данные через Base64 и сохранить их как одно значение
CodesInChaos,
11
@ da4c30ff Несмотря на практичность метаданных, у стеганографии есть определенный крутой фактор шпионских фантазий, которому нашей толпе трудно противостоять. Если бы я делал это сам, я бы использовал предложенный Джошем Петри метод для масштабируемости, но у меня был бы очень большой соблазн использовать стеганографию, чтобы скрыть контрольную сумму в самом изображении, чтобы убедиться, что изображение и текст принадлежат друг другу - не потому, что это полезно или безопасно, но только потому, что это круто. ;)
Д.М.Григорий
Что именно здесь означает «текст»? Только ASCII (символ <= 127)? Любой байт кроме 0? Любой байт вообще? Или что-то другое? (Это повлияет на кодировку, которую вы должны использовать для записи двоичных данных. Например, нужна ли вам base64 или нет.)
svick
1
Я обновил ответ со ссылкой на стандарт для текстового блока; но в основном текст интерпретируется в соответствии с ISO 8859-1 (8-разрядные однобайтовые символы Latin-1).
Джош
51

Разработчик Монако действительно сделал отличную статью о том, как они и Spore достигли этого.

Основная сводка того, что они делают, довольно проста:

  • Преобразуйте ваши данные в двоичный файл
  • Преобразование целевого изображения в необработанное растровое изображение
  • Пройдите по пикселям изображения в некотором предсказуемом порядке (они просто идут слева направо из верхнего левого угла).
  • Запишите один бит в бит самого низкого порядка каждого цветового канала каждого пикселя
  • Снова экспортируйте измененное растровое изображение в png

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

Основная идея этого процесса заключается в том, что в изображении много пикселей, а биты младшего разряда каждого цветового канала не имеют большого значения. значения. Кроме того, около половины написанных вами битов будут такими же, какими были биты в изображении. То, что вы получите, по сути, правильное изображение, но со странными артефактами. Он тратит время, чтобы заметить, что эти артефакты действительно заметны, только если вы действительно проверяете контрастность / насыщенность и увеличение. Однако у него есть исходные изображения с большим количеством начальных шумов.

Из статьи:

Обратите внимание, что на последнем изображении едва заметна горизонтальная линия в шуме. Это конец данных уровня. Это означает, что я могу фактически вписать все данные уровня в изображение размером 265x120 пикселей, используя только младший бит.

ПОЛЕЗНОЕ ДОБАВЛЕНИЕ:

Что-то, что я мог сделать, и я полагаю, что люди Spore сделали то же самое, фактически используют ВСЕ цветовые биты в пикселях, которые на 100% прозрачны. Поскольку эти пиксели прозрачны, не имеет значения, какой цвет вы им зададите.

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

Зачем предпочитать эту технику, а не просто хранить ее в метаданных?

  • Это веселее! :)
  • Сервисы могут манипулировать метаданными (возможно, как функция конфиденциальности / безопасности), но не должны манипулировать пикселями вашего png, если у них нет агрессивных требований к размещению изображений (глядя на вас, facebook). Но если они полностью реэкспортируют ваше изображение, вы ничего не сможете с этим сделать.

Дополнительный кредит: чтобы уменьшить заметность шума, вы можете использовать PRNG с фиксированным начальным числом для выбора пикселей для модификации. Вы также можете изменить некоторые цветовые каналы только аналогичным образом.

Алексис Бессесснер
источник
6
Существуют стеганографические алгоритмы, которые более устойчивы к масштабированию изображения / настройке цвета, чем метод Монако. (Хотя они обычно хранят данные с существенно меньшей плотностью) Один из примеров - это водяные знаки, используемые в скриншотах World of Warcraft: owncore.com/forums/world-of-warcraft/…
DMGregory
@DMGregory Хорошая находка! Точный алгоритм, который вы выберете, должен определяться вашим конкретным вариантом использования (пространство, долговечность, секретность и т. Д.).
Алексис Бессесснер
1
Как бы круто это не звучало, это плохая идея. PNG изображения используют сжатие изображений без потерь; возиться с младшими битами изображения, скорее всего , сделать файл больше в то же время , как это (немного) снижает качество изображения. Абсолютно любая информация может быть закодирована как «текст», поэтому использование фрагмента метаданных является, очевидно, правильным способом сделать это; кто-то возится с кусочками изображения, не нуждаясь в стеганографии, просто выскочив из колеи.
dfeuer
1
@dfeuer - Очевидно, что и Spore, и Monaco использовали игровые платформы, в которых есть конвейер загрузки ресурсов, который сокращает .PNG до чистого растрового изображения, поэтому блоки метаданных не проходили через него.
Рассел Борогове
1
@dfeuer Я сделал несколько наивных тестов. Подход метаданных, по-видимому, добавляет около 80% размера, добавляемого с помощью стенографического подхода, при записи 100 КБ случайных битов в изображение размером 1920x1080 пикселей. Проверено на чистом изображении и скриншоте рабочего стола. Не совсем катастрофическая разница, но meatadata определенно лучше (и более последовательна), если вы действительно обеспокоены размером более 40 КБ. Обратите внимание, что метаданные все еще были довольно неэффективными. Я получил 181 КБ за запись 100 КБ данных! Может быть место для оптимизации, как строка закодирована или что-то.
Алексис Бессесснер
7

Я скачал и исследовал несколько существ Spore из Sporepedia. От тех, кого я узнал, что:

  • Изображения не содержат никакой информации в дополнение к стандартным данным изображения.
  • Стенографические данные были сохранены без учета изображения, можно предположить, что прозрачные части использовались исключительно, но это не так.
  • Использование хранилища зависит от объема информации, которая должна быть сохранена, некоторые изображения используют только младший значащий бит для хранения данных, некоторые используют два младших значащих бита, некоторые могут использовать больше.
  • Формат Spore позволяет избежать использования бита только для одной части изображения, младший значащий бит изменяется по всему изображению, если используется второй младший значащий бит, он используется для всего изображения. Предположительно это делается с использованием случайного заполнения. Это позволяет избежать изменения качества, которое может быть более тревожным для зрителя, чем сам шум.
  • Все четыре канала используются одинаково, канал непрозрачности не подвергается специальной обработке, поэтому некоторые прозрачные пиксели слегка непрозрачны, а некоторые непрозрачные пиксели слегка прозрачны.

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

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

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

Возможные простые улучшения формата Spore включают в себя:

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