Як я можу зберігати метадані гри у файлі .png?


208

Спора дозволяє поділитися створеними гравцем істотами, експортуючи .pngфайл. Це .pngфото істоти, але якщо вона імпортується в гру, інформація істоти (наприклад, текстури, розмір і форма) також приходить разом з нею.

Як я можу реалізувати таку функцію?


5
Має мати набагато вищий бал, це дуже цікаве питання.
П’єр Арло

3
Альфа-канал може бути частково зловживаний для цього ...
Тобіас Кіенцлер

3
Можливо, використання: stackoverflow.com/questions/9542359/…
logic-unit

1
Я думаю, що краще зберегти ці дані в іншому файлі. У цьому файлі має бути назва текстурного файлу, пов’язаного з об'єктом, для якого потрібно зберігати дані. По-перше, задля виразності (формат png призначений для графіки - "Портативна мережева графіка"), по-друге: врахуйте ситуацію, коли ви хотіли зберегти більше зображень із сутністю, ви можете просто додати посилання на неї з цього спеціального файлу. Напевно у вас буде проблема із зберіганням різних зображень (різного розміру, різної глибини тощо) в одному PNG.
luke1985

3
Альфа-канал багато згадувався, і, звичайно, PNG так чи інакше підтримують метадані, але я просто думав, що поділюсь технікою, якою я користувався - переступаючи ліворуч праворуч, зверху вниз та через канали у фіксованому порядку , а округлення значень до коефіцієнтів або рівностей - не має значення, чи вони вгору чи вниз. Зміна 1 на БУДЬ-який із каналів не робить помітної різниці, і у зображенні 256х256 (звичайно, 4 біти на піксель) ви можете зберігати вражаючі 32 КБ даних. Якщо вам потрібно ще більше, ви можете округлити% 4 замість цього - занадто багато , і він починає виглядати як старий GIF розуму ..
Octopoid

Відповіді:


56

Якщо вам справді потрібен файл PNG, швидше за все, вони просто додали інформацію у файл. Це фактично практика стеганографії . Багато разів це використовується для приховування корисних навантажень або секретних повідомлень у речах, які, здавалося б, стикаються з громадськістю. Однак в цьому випадку, ймовірно, саме цей метод був використаний. Типова Stegongraphy не зможе приховати вміст, але немає жодної причини, через яку не можна було просто додати дані із зображення в кінці файлу та отримати їх.

Кілька інструментів кодують ці дані для вас, пошук у Google відображає принаймні це і це .

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

Однак, подальше дослідження, отримане іншими відповідями, та пошук у Google виявляє, що Спора насправді використовувала лише версію Стенографії, щоб приховати інформацію в альфа-бітах. Маючи це на увазі, ми можемо виключити можливість додавання даних або метаданих.

Слід зазначити, що метадані залишаються дуже життєздатним вибором, якщо дані аналізуються локально. Якщо ця інформація може бути обмінена в Інтернеті або повторно закодована, експорт не гарантує збереження всієї вашої інформації. Якщо використовуються дані пікселів, вони можуть переживати безрезультатні перетворення без проблем.


3
Наскільки мені відомо, спора зберігає метадані всередині альфа-каналу PNG.
Тара

28
Навіщо використовувати альфа-канал або стеганографію, коли PNG підтримує довільні фрагменти метаданих?
Рассел Борогов

8
"PNG має байтний підпис" 89 "на початку, тому дуже ймовірно, що інформація була вставлена ​​до або після самої структури PNG і просто проаналізована грою SPORE. Якщо це було так, тоді воно не буде більше не бути файлом PNG. Тобто переглядачі звичайних зображень не зможуть його відобразити.
svick

3
@RussellBorogove одна досить вагома причина: якщо PNG декодується / кодується чимось окрім Спори, довільні фрагменти метаданих, швидше за все, будуть ігноровані або втрачені, ніж фактичні дані зображення. Кодування даних на зображенні покращує ймовірність того, що якщо ви зможете їх побачити, ви можете їх завантажити .
Тім С.

@svick Насправді я грав із файлом, який був і дійсним PNG, і RAR. Заголовок RAR запустився після PNG, а екстрактори RAR були нормальними. Це може добре працювати і в інший спосіб.
корти

153

Формат PNG підтримує більш-менш довільні метадані. Стандарт PNG визначає файл PNG, по суті, це фрагменти, деякі з яких необхідні (і містять дані зображення). Інші, однак, необов’язкові. Наприклад, є шматок для зберігання гамма-інформації або даних гістограми.

Зокрема, є tEXtфрагмент, який можна використовувати для зберігання довільних пар ключів / значень тексту. Це можна використовувати для переміщення будь-якого типу будь-яких довільних даних, які ви хочете, за умови, що ви можете представити ці дані у вигляді тексту (що досить вірогідно).

Вам знадобиться бібліотека PNG, яка дозволяє отримувати доступ та маніпулювати цими додатковими фрагментами (наприклад, довідковою бібліотекою ), або вам потрібно буде написати їх самостійно. Тоді лише питання вибору того, як кодувати потрібні дані як пари ключів / значень. Я б запропонував таке:

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

В інтересах отримання більш повної відповіді я також зазначу, що існує ще один підхід (раніше задокументований відповідями @Vaughn та @ Alexisis): кодуйте додаткові дані, які ви хочете безпосередньо, у ваших зображеннях пікселів, розподіляючи ваші дані по всіх біти низького порядку кольорових каналів. Цей підхід не вимагає використання додаткових метаданих, а це означає, що ви можете їх повністю реалізувати, не покладаючись на них або переживаючи за те, що зовнішні програми неправильно обробляють ці метадані. Також у нього дуже високий "крутий" коефіцієнт, і оскільки ви використовуєте лише біти низького порядку, зображення все одно буде виглядати правильним для людського ока. Однак це означає, що розмір зображення є основним контрольним фактором для кількості даних, які ви можете зберігати; якщо вам потрібно більше місця, вам потрібно буде виділити більше пікселів для зображення.

Як зазначали інші, цей процес відомий як стеганографія .


3
Можна просто надсилати дані через Base64 і зберігати їх як єдине значення
CodesInChaos

11
@ da4c30ff Наскільки практичні метадані, стеганографія має певний класний фактор шпигунської фантазії, якому важко протистояти нашому натовпу. Якби я робив це сам, я б застосував запропонований Джошем Петрі метод для масштабування, але я б сильно спокусився використати стеганографію, щоб приховати контрольну суму в самому зображенні, щоб переконатися, що зображення та текст належать один одному - не тому, що це корисно чи безпечно, але лише тому, що це круто. ;)
DMGregory

Що саме тут означає "текст"? Тільки ASCII (символ <= 127)? Будь-який байт, крім 0? Будь-який байт взагалі? Або щось інше? (Це вплине на кодування, яке потрібно використовувати для запису бінарних даних. Наприклад, вам потрібно base64 чи ні.)
svick

1
Я оновив відповідь посиланням на стандарт для текстового фрагменту; але в основному текст інтерпретується відповідно до ISO 8859-1 (8-бітові, однобайтові, латинські-1 символи).
Джош

51

Розробник Монако насправді зробив чудову статтю про те, як вони і Спора досягли цього.

Основний підсумок того, що вони роблять, досить простий:

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

Просто зробіть це в зворотному порядку, щоб отримати свої дані.

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

Зі статті:

На останньому зображенні зауважте, як у шумі ледь помітна горизонтальна лінія. Ось і закінчуються дані рівня. Це означає, що я фактично можу вмістити всі дані рівня в зображення 265x120 пікселів, лише використовуючи найменш значущий біт.

ДОДАТКУВАННЯ ТРИКІВ:

Щось я міг би зробити, і я вважаю, що люди Спори так само, як насправді, використовують ВСЕ кольорові біти в пікселях, які на 100% прозорі. Оскільки ці пікселі прозорі, не має значення, для якого кольору ви їх встановите.

Я не можу цього зробити, оскільки використовую все зображення, це означає, що у мене немає прозорих пікселів, з якими можна працювати.

Навіщо надавати перевагу цій техніці, а не просто зберігати її у метаданих?

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

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


6
Існують стеганографічні алгоритми, які є більш надійними щодо масштабування зображення / коригування кольорів, ніж метод Монако. (Хоча вони зазвичай зберігають дані в істотно більш низької щільності) Одним з прикладів є створення водяних знаків використовується в World Of Warcraft скріншоти: ownedcore.com/forums/world-of-warcraft / ...
DMGregory

@DMGregory Приємна знахідка! Точний алгоритм, який ви обираєте, звичайно, повинен визначатися вашим конкретним випадком використання (простір, довговічність, секретність тощо).
Алексіс Вессенснер

1
Як круто це не звучить, це погана ідея. Зображення PNG використовують стиснення зображень без втрат ; сповзання з низькими бітами зображення, ймовірно, зробить файл більшим одночасно, оскільки це (трохи) знижує якість зображення. Абсолютно будь-яку інформацію можна закодувати як "текст", тому використання фрагмента метаданих - це очевидно правильний спосіб зробити це; хтось, що перебирає біти зображення, не потребуючи стеганографії, - це просто вискочування коліс.
dfeuer

1
@dfeuer - Мабуть, і Spore, і Монако використовували ігрові рамки, у яких є конвеєр завантаження активів, який позбавляє.
Рассел Борогов

1
@dfeuer Я зробив кілька наївних тестів. Підхід до метаданих додає приблизно 80% розміру, який додається стенографічним підходом, коли записується 100 КБ випадкових біт до зображення 1920x1080px. Тестується на екрані порожнього зображення та на робочому столі. Не зовсім катастрофічна різниця, але метадані, безумовно, кращі (і послідовніші), якщо ви дійсно переживаєте понад 40 кБ. Зауважимо, що метадані все ще були досить неефективними. Я набрав 181 кБ для запису 100 кБ даних! Може бути поле для оптимізації того, як кодується рядок чи щось таке.
Alexis Beingessner

7

Я завантажив і оглянув кілька спорових істот із Спорепедії. З тих, хто дізнався, що:

  • Зображення не містять інформації крім стандартних даних про зображення.
  • Стенографічні дані зберігаються без урахування зображення, можна було б уявити, що прозорі деталі використовуються виключно, але це не так.
  • Використання пам’яті залежить від кількості інформації, яку потрібно зберегти, деякі з зображень використовували лише найменш значущий біт для зберігання даних, деякі використовували два найменш значущі біти, деякі можуть використовувати більше.
  • Формат Spore дозволяє уникнути використання лише однієї частини зображення, найменш значущий біт змінюється протягом усього зображення, якщо використовується другий найменш значущий біт, він використовується для всього зображення. Імовірно, це робиться за допомогою випадкових накладок. Це дозволяє уникнути зміни якості, які можуть бути більш тривожними для глядача, ніж сам шум.
  • Усі чотири канали використовуються однаково, канал непрозорості не отримує особливої ​​обробки, тому деякі прозорі пікселі злегка непрозорі, а деякі непрозорі пікселі - злегка прозорі.

Варто зазначити, що це саме те, що робить Spore, це метод, який ставить простоту перед більшістю інших проблем.

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

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

Можливі прості вдосконалення формату Spore включають:

  • Використовуйте лише або віддайте перевагу використанню значень кольору прозорих пікселів, вони не мають візуальної різниці.
  • Використовуйте синій канал більше, а зелений канал менше, синій колір має менший сприйнятий вплив на зображення.
  • Зберігаючи яскравість кожного пікселя близькою до незмінних та кодуючи дані за кольором, невеликий шум у цьому параметрі практично не виявляється для людини.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.