Wie kann ich Spielmetadaten in einer PNG-Datei speichern?


208

Mit Spore können vom Spieler erstellte Kreaturen durch Exportieren einer .pngDatei geteilt werden. Das .pngist ein Foto der Kreatur, aber wenn es in das Spiel importiert wird, werden auch die Informationen der Kreatur (wie Texturen, Größe und Form) mitgeliefert.

Wie kann ich eine solche Funktion implementieren?


5
Sollte eine viel höhere Punktzahl haben, ist das eine sehr interessante Frage.
Pierre Arlaud

3
Der Alphakanal könnte teilweise dafür missbraucht werden ...
Tobias Kienzler

3
Möglicherweise von Nutzen: stackoverflow.com/questions/9542359/…
logic-unit

1
Ich denke, es ist besser, diese Daten in einer anderen Datei zu speichern. In dieser Datei sollte sich der Name der Texturdatei befinden, die sich auf eine Entität bezieht, in der Daten gespeichert werden sollen. Erstens aus Gründen der Klarheit (PNG-Format für Grafiken - "Portable Network Graphics"), zweitens: Stellen Sie sich eine Situation vor, in der Sie mehr Bilder mit einer Entität speichern möchten, und fügen Sie einfach Verweise aus dieser benutzerdefinierten Datei hinzu. Sie werden wahrscheinlich Probleme haben, verschiedene Bilder (unterschiedliche Größe, unterschiedliche Tiefe usw.) in einem PNG zu speichern.
Luke1985

3
Der Alpha-Kanal wurde schon oft erwähnt, und PNGs unterstützen natürlich auch Metadaten, aber ich dachte nur, ich würde eine von mir verwendete Technik teilen - von links nach rechts, von oben nach unten und durch die Kanäle in einer festgelegten Reihenfolge und Runden der Werte auf Gewinnchancen oder Gewinnchancen - spielt keine Rolle, ob es hoch oder runter ist. Eine Änderung von 1 in JEDEM der Kanäle macht keinen merklichen Unterschied, und in einem 256x256-Bild (natürlich mit 4 Bit pro Pixel) können Sie beeindruckende 32 KB an Daten speichern. Wenn Sie noch mehr brauchen, können Sie stattdessen auf% 4 runden - zu viel und es sieht aus wie ein alter GIF-Geist.
Octopoid

Antworten:


56

Wenn alles, was Sie wirklich brauchten, die PNG-Datei war, haben Sie wahrscheinlich nur die Informationen in die Datei eingefügt. Dies ist eigentlich eine Praxis der Steganographie . In vielen Fällen wird dies verwendet, um Nutzdaten oder geheime Nachrichten in scheinbar öffentlich zugänglichen Objekten zu verbergen. In diesem Fall ist es jedoch wahrscheinlich, dass diese Methode angewendet wurde. Die typische Stegongraphie tut alles, um den Inhalt zu verbergen, aber es gibt keinen Grund, warum man die Daten nicht einfach am Ende der Datei aus dem Bild anhängen und abrufen könnte.

Mehrere Tools verschlüsseln diese Daten für Sie, eine Google-Suche bringt zumindest dies und das auf den Punkt .

Ein PNG hat $89zu Beginn die Bytesignatur, sodass es möglich ist, dass die Informationen nach der PNG-Struktur selbst eingefügt und vom SPORE-Spiel einfach analysiert wurden.

Weitere Untersuchungen der anderen Antworten und eine Suche bei Google haben jedoch ergeben, dass Spore tatsächlich nur eine Version von Stegongraphy verwendete, um die Informationen in den Alphabits zu verbergen. In diesem Sinne können wir die Möglichkeit von angehängten Daten oder Metadaten ausschließen.

Es sollte beachtet werden, dass Metadaten immer noch eine sehr sinnvolle Wahl sind, wenn die Daten lokal analysiert werden. Wenn diese Informationen im Internet geteilt oder neu codiert werden, wird beim Export nicht garantiert, dass alle Ihre Informationen erhalten bleiben. Wenn Pixeldaten verwendet werden, können sie verlustfreie Konvertierungen problemlos überstehen.


3
Soweit ich weiß, hat Spore Metadaten im Alphakanal des PNG gespeichert.
Tara

28
Warum Alphakanal oder Steganographie verwenden, wenn PNG beliebige Metadaten-Chunks unterstützt?
Russell Borogove

8
"Ein PNG hat zu Beginn die Bytesignatur" 89 ", daher ist es sehr wahrscheinlich, dass die Informationen vor oder nach der PNG-Struktur selbst eingefügt und einfach vom SPORE-Spiel analysiert wurden." Keine PNG-Datei mehr. Das heißt, übliche Bildbetrachter könnten es nicht anzeigen.
Svick

3
@RussellBorogove ein ziemlich guter Grund: Wenn das PNG von etwas anderem als Spore dekodiert / kodiert wird, werden beliebige Metadaten-Chunks mit größerer Wahrscheinlichkeit ignoriert oder gehen verloren als tatsächliche Bilddaten. Das Codieren der Daten im Bild erhöht die Wahrscheinlichkeit, dass Sie sie laden können , wenn Sie sie sehen .
Tim S.

@svick Eigentlich habe ich mit einer Datei gespielt, die sowohl ein gültiges PNG als auch RAR war. Der RAR-Header wurde nach dem PNG gestartet und die RAR-Extrahierer waren in Ordnung. Es kann auch in der anderen Richtung gut funktionieren.
Cortices

153

Das PNG-Format unterstützt mehr oder weniger beliebige Metadaten. Der PNG-Standard definiert eine PNG-Datei, im Wesentlichen eine Reihe von Abschnitten, von denen einige erforderlich sind (und die Bilddaten enthalten). Andere sind jedoch optional. Zum Beispiel gibt es einen Block zum Speichern von Gammainformationen oder Histogrammdaten.

Insbesondere gibt es einen tEXtBlock , in dem beliebige Schlüssel / Wert-Textpaare gespeichert werden können. Dies kann verwendet werden, um beliebige Daten zu versenden, vorausgesetzt, Sie können diese Daten als Text darstellen (was ziemlich wahrscheinlich ist).

Sie benötigen eine PNG-Bibliothek, mit der Sie auf diese zusätzlichen Blöcke (z. B. die Referenzbibliothek ) zugreifen und sie bearbeiten können , oder Sie müssen selbst eine erstellen. Dann müssen Sie nur noch auswählen, wie die gewünschten Daten als Schlüssel / Wert-Paare codiert werden sollen. Ich würde folgendes vorschlagen:

  • Wählen Sie Schlüsselnamen, denen der Name Ihres Projekts oder der Codename vorangestellt ist, um ein grobes "Namespace" -System zu erstellen und mögliche Konflikte mit der Verwendung der Daten durch andere Anwendungen zu vermeiden
  • Versuchen Sie nicht, tatsächliche Texturen auf diese Weise zu speichern, sondern speichern Sie Verweise auf die Texturen, die auf die eigene Asset-Datenbank Ihres Spiels verweisen
  • Daten wie Größe, Gewicht usw. von Kreaturen oder Objekten - im Grunde genommen einfache Skalare - können trivial gespeichert werden

Im Interesse einer vollständigeren Antwort möchte ich auch darauf hinweisen, dass es einen anderen Ansatz gibt (der zuvor durch die Antworten von @Vaughn und @ Alexis dokumentiert wurde): Kodieren Sie die zusätzlichen Daten, die Sie möchten, direkt in Ihre Bildpixel und verteilen Sie Ihre Daten auf mehrere die niederwertigen Bits der Farbkanäle. Für diesen Ansatz sind keine zusätzlichen Metadaten erforderlich. Dies bedeutet, dass Sie ihn vollständig implementieren können, ohne sich darauf verlassen zu müssen oder sich Sorgen über externe Programme zu machen, die diese Metadaten falsch verarbeiten. Es hat auch einen sehr hohen "coolen" Faktor, und da Sie nur Bits niedriger Ordnung verwenden, sieht das Bild für das menschliche Auge immer noch korrekt aus. Dies bedeutet jedoch, dass Ihre Bildgröße ein primärer Steuerungsfaktor für die Datenmenge ist, die Sie speichern können. Wenn Sie mehr Speicherplatz benötigen, müssen Sie dem Bild mehr Pixel zuweisen.

Wie bereits erwähnt, wird dieser Prozess als Steganographie bezeichnet .


3
Man könnte die Daten einfach über Base64 senden und als Einzelwert speichern
CodesInChaos

11
@ da4c30ff So praktisch Metadaten auch sein mögen, Steganografie hat einen gewissen coolen Spionagefaktor, dem sich unsere Masse nur schwer widersetzen kann. Wenn ich das selbst machen würde, würde ich Josh Petries vorgeschlagene Methode für die Skalierbarkeit verwenden, aber ich wäre sehr versucht, eine Prüfsumme im Bild selbst mithilfe der Steganografie auszublenden, um zu überprüfen, ob Bild und Text zueinander gehören - nicht weil Das ist nützlich oder sicher, aber nur, weil es cool ist. ;)
DMGregory

Was bedeutet hier genau "Text"? Nur ASCII (Zeichen <= 127)? Beliebiges Byte außer 0? Irgendein Byte? Oder etwas anderes? (Dies wirkt sich auf die Codierung aus, die Sie zum Schreiben von Binärdaten verwenden müssen. ZB ob Sie base64 benötigen oder nicht.)
svick

1
Ich habe die Antwort mit einem Link zum Standard für den Textabschnitt aktualisiert. Grundsätzlich wird der Text jedoch gemäß ISO 8859-1 (8-Bit, Einzelbyte, lateinische 1-Zeichen) interpretiert.
Josh

51

Der Entwickler von Monaco hat tatsächlich einen hervorragenden Artikel darüber verfasst, wie sowohl sie als auch Spore dies erreicht haben.

Die grundlegende Zusammenfassung ihrer Tätigkeit ist recht einfach:

  • Konvertieren Sie Ihre Daten in Binärdateien
  • Konvertieren Sie Ihr Zielbild in eine rohe Bitmap
  • Gehen Sie entlang der Pixel des Bildes in einem vorhersehbaren Muster (von links oben nach rechts).
  • Schreiben Sie ein Bit in das Bit niedrigster Ordnung jedes Farbkanals jedes Pixels
  • Exportieren Sie die geänderte Bitmap erneut nach png

Tun Sie dies einfach in umgekehrter Reihenfolge, um Ihre Daten abzurufen.

Die Grundidee hinter dem Prozess ist, dass ein Bild viele Pixel enthält und die niedrigstwertigen Bits jedes Farbkanals keinen großen Unterschied machen. Darüber hinaus entspricht etwa die Hälfte der Bits, die Sie schreiben, dem Bit im Bild, das bereits vorhanden war. Was Sie zurückerhalten, ist im Wesentlichen das richtige Bild, aber mit seltsamen Artefakten. Er nimmt sich die Zeit zu bemerken, dass diese Artefakte nur dann wirklich auffallen, wenn Sie den Kontrast / die Sättigung wirklich ankurbeln und hineinzoomen. Er hat jedoch Quellbilder mit viel Anfangsrauschen.

Aus dem Artikel:

Beachten Sie im letzten Bild, dass das Rauschen eine kaum wahrnehmbare horizontale Linie aufweist. Das ist das Ende der Leveldaten. Das bedeutet, dass ich tatsächlich alle Level-Daten in ein 265 x 120 Pixel großes Bild einpassen kann, nur mit dem niedrigstwertigen Bit.

Ein kniffliges Addendum:

Etwas, das ich tun könnte, und ich glaube, dass es auch die Sporen getan haben, ist tatsächlich, ALLE Farbbits in Pixeln zu verwenden, die 100% transparent sind. Da diese Pixel transparent sind, spielt es keine Rolle, auf welche Farbe Sie sie einstellen.

Ich kann dies jedoch nicht tun, da ich das gesamte Bild verwende, was bedeutet, dass ich keine transparenten Pixel zum Arbeiten habe.

Warum sollte diese Technik der Speicherung in den Metadaten vorgezogen werden?

  • Es ist lustig! :)
  • Dienste können Metadaten entstellen (möglicherweise als Datenschutz- / Sicherheitsmerkmal), sollten jedoch die Pixel Ihres PNG nicht entstellen, es sei denn, sie stellen aggressive Anforderungen an das Hosting von Bildern (wenn Sie sich umsehen, Facebook). Aber wenn sie vollständig Ihr Bild wieder zu exportieren gibt es nichts , was man zuverlässig kann tun.

Zusätzliches Guthaben: Um die Wahrnehmbarkeit von Rauschen zu verringern, können Sie die zu ändernden Pixel mit einem PRNG mit festem Startwert auswählen. Sie können auch nur einige der Farbkanäle auf ähnliche Weise ändern.


6
Es gibt steganographische Algorithmen, die robuster gegen Bildskalierung / Farbanpassung sind als die Monaco-Methode. (Obwohl sie Daten im Allgemeinen mit einer wesentlich geringeren Dichte speichern) Ein Beispiel ist das in World of Warcraft-Screenshots verwendete Wasserzeichen: ownedcore.com/forums/world-of-warcraft/…
DMGregory

@DMGregory Schöne Entdeckung! Der genaue Algorithmus, den Sie auswählen, sollte natürlich von Ihrem speziellen Verwendungszweck (Platz, Haltbarkeit, Geheimhaltung usw.) bestimmt werden.
Alexis Beingessner

1
So cool das auch klingen mag, es ist eine schlechte Idee. PNG - Bilder verwenden lossless Bildkomprimierung; Wenn Sie mit den niedrigen Bits des Bildes herumspielen, wird die Datei wahrscheinlich gleichzeitig größer, da sie die Bildqualität (geringfügig) verringert. Absolut jede Information kann als "Text" codiert werden, daher ist die Verwendung eines Metadaten-Chunks die offensichtlich richtige Methode, um dies zu tun. Jemand, der am Bild herumfummelt, ohne tatsächlich Steganografie zu benötigen, macht einfach Spaß.
Dfeuer

1
@dfeuer - Anscheinend verwendeten sowohl Spore als auch Monaco Spiel-Frameworks, die über eine Pipeline zum Laden von Assets verfügten, die die .PNG-Datei auf eine leere Bitmap herunterfuhr, sodass die Metadaten-Chunks es nicht schafften.
Russell Borogove

1
@dfeuer Ich habe ein paar naive Tests gemacht. Der Metadaten-Ansatz scheint etwa 80% der durch den stenografischen Ansatz hinzugefügten Größe hinzuzufügen, wenn 100 kB zufällige Bits in ein 1920 x 1080 Pixel großes Bild geschrieben werden. Getestet mit einem leeren Bild und einem Desktop-Screenshot. Nicht gerade ein katastrophaler Unterschied, aber meatadata ist sicherlich besser (und konsistenter), wenn Sie wirklich über 40 KB besorgt sind. Beachten Sie, dass Metadaten immer noch ziemlich ineffizient waren. Ich habe 181 KB für das Schreiben von 100 KB Daten gewonnen! Könnte Raum sein, um zu optimieren, wie der String codiert ist oder so.
Alexis Beingessner

7

Ich habe ein paar Sporenkreaturen von Sporepedia heruntergeladen und untersucht. Von denen habe ich gelernt, dass:

  • Die Bilder enthalten keine zusätzlichen Informationen zu den Standardbilddaten.
  • Die stenografischen Daten wurden ohne Rücksicht auf das Bild gespeichert, man könnte sich vorstellen, dass die transparenten Teile ausschließlich verwendet wurden, sind es aber nicht.
  • Die Speichernutzung hängt von der Menge der Informationen ab, die gespeichert werden müssen. Einige der Bilder verwendeten nur das niedrigstwertige Bit für die Datenspeicherung. Einige verwendeten die zwei niedrigstwertigen Bits. Einige verwenden möglicherweise mehr.
  • Das Spore-Format vermeidet die Verwendung eines Bits nur für einen Teil des Bildes. Das niedrigstwertige Bit ändert sich im gesamten Bild. Wenn das zweitniedrigstwertige Bit verwendet wird, wird es für das gesamte Bild verwendet. Dies geschieht vermutlich durch zufälliges Auffüllen. Dies vermeidet eine Qualitätsverschiebung, die für den Betrachter störender sein könnte als das Rauschen selbst.
  • Alle vier Kanäle werden gleichermaßen verwendet, der Opazitätskanal wird nicht speziell behandelt, daher sind einige der transparenten Pixel leicht opak, während einige der opaken Pixel leicht transparent sind.

Es ist erwähnenswert, dass dies genau das ist, was Spore tut. Es ist eine Methode, die die Einfachheit vor die meisten anderen Bedenken stellt.

Die Wahl der Verwendung von Stenografie anstelle eines zusätzlichen Datenblocks bedeutet, dass die Daten überleben, wenn das Bild neu codiert wird, beispielsweise von einer Website, obwohl es die Skalierung oder die JPEG-Komprimierung nicht überlebt.

Ich denke, dass die prominenteste Alternative darin besteht, nur eine ID im Bild zu kodieren und die tatsächlichen Daten auf einem zentralen Server zu speichern, auf dem diese ID gegen die genauen Kreaturendaten ausgetauscht werden kann. Eine solche ID wäre kurz genug, um in einem skalierungs- und komprimierungstoleranten Stenografieformat codiert zu werden.

Mögliche einfache Verbesserungen des Spore-Formats sind:

  • Verwenden Sie nur die Farbwerte transparenter Pixel oder bevorzugen Sie diese, da dies keinen visuellen Unterschied macht.
  • Verwenden Sie den blauen Kanal mehr und den grünen Kanal weniger. Die blaue Farbe wirkt sich weniger auf das Bild aus.
  • Wenn die Luminanz jedes Pixels nahezu unverändert bleibt und die Daten in Chroma codiert werden, ist ein geringes Rauschen in diesem Parameter für den Menschen praktisch nicht erkennbar.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.