Come posso archiviare i metadati del gioco in un file .png?


208

Spore consente di condividere le creature create dal giocatore esportando un .pngfile. Questa .pngè una foto della creatura, ma se viene importata nel gioco, anche le informazioni della creatura (come trame, dimensioni e forma) vengono fornite con essa.

Come posso implementare una tale funzione?


5
Dovrebbe avere un punteggio molto più alto, questa è una domanda molto interessante.
Pierre Arlaud,

3
Il canale alfa potrebbe essere parzialmente maltrattato per questo ...
Tobias Kienzler,


1
Penso che sia meglio archiviare questi dati in un altro file. In questo file, dovrebbe esserci il nome del file di trama relativo a un'entità in cui si desidera memorizzare i dati. In primo luogo per motivi di chiarezza (il formato png è per la grafica - "Portable Network Graphics"), in secondo luogo: considera una situazione in cui desideri archiviare più immagini con un'entità, puoi semplicemente aggiungere riferimenti ad esso da quel file personalizzato. Probabilmente avrai problemi a memorizzare immagini diverse (dimensioni diverse, profondità diversa ecc.) In un solo PNG.
luke1985,

3
Il canale alfa è stato menzionato pesantemente e, naturalmente, i PNG supportano comunque i metadati, ma ho solo pensato di condividere una tecnica che ho usato: passare da sinistra a destra, dall'alto verso il basso e attraverso i canali in un ordine fisso e arrotondando i valori a probabilità o dispari - non importa se è su o giù. Una variazione di 1 in QUALSIASI dei canali non fa alcuna differenza, e in un'immagine 256x256 (ovviamente a 4 bit per pixel), è possibile archiviare 32 KB di dati. Se hai bisogno ancora di più, puoi arrotondare a% 4 invece - troppo e inizia a sembrare una vecchia mente GIF ..
Octopoid,

Risposte:


56

Se tutto ciò di cui hai veramente bisogno era il file PNG, è probabile che abbiano semplicemente aggiunto le informazioni nel file. Questa è in realtà una pratica di steganografia . Molte volte, questo è usato per nascondere payload o messaggi segreti in cose che apparentemente sono di fronte al pubblico. Tuttavia, è probabile in questo caso che questo metodo sia quello che è stato utilizzato. La tipica Stegongraphy farà di tutto per nascondere il contenuto, ma non c'è motivo per cui non si possa semplicemente aggiungere i dati dall'immagine alla fine del file e recuperarli.

Diversi strumenti codificano questi dati per te, una ricerca su Google fa apparire almeno questo e questo .

Un PNG ha la firma del byte $89all'inizio, quindi è possibile che le informazioni siano state inserite dopo la struttura PNG stessa e semplicemente analizzate dal gioco SPORE.

Tuttavia, ulteriori ricerche fornite dalle altre risposte e una ricerca su Google rivelano che Spore stava effettivamente utilizzando solo una versione di Stegongraphy per nascondere le informazioni nei bit alfa. Tenendo presente ciò, possiamo escludere la possibilità di aggiungere dati o metadati.

Va notato che i metadati sono ancora una scelta molto praticabile, se i dati vengono analizzati localmente. Se tali informazioni potrebbero essere condivise sul Web o ricodificate, l'esportazione non è garantita per conservare tutte le informazioni. Quando vengono utilizzati i dati pixel, possono sopravvivere conversioni senza perdita senza problemi.


3
Per quanto ne so, i metadati memorizzati nella spora sono stati inseriti nel canale alfa del PNG.
Tara,

28
Perché usare il canale alfa o la steganografia quando PNG supporta blocchi di metadati arbitrari?
Russell Borogove,

8
"Un PNG ha la firma del byte" 89 "all'inizio, quindi è molto probabile che le informazioni siano state inserite prima o dopo la struttura PNG stessa e semplicemente analizzate dal gioco SPORE." Se così fosse, allora non lo farebbe ' essere più un file PNG. Cioè i comuni visualizzatori di immagini non sarebbero in grado di visualizzarlo.
svick,

3
@RussellBorogove una ragione abbastanza buona: se il PNG è decodificato / codificato da qualcosa oltre a Spore, è più probabile che blocchi di metadati arbitrari vengano ignorati o persi rispetto ai dati immagine reali. La codifica dei dati nell'immagine migliora la probabilità che se riesci a vederli, puoi caricarli .
Tim S.

@svick In realtà, ho giocato con un file che era sia un PNG che un RAR validi. L'intestazione RAR è iniziata dopo il PNG e gli estrattori RAR erano a posto. Può funzionare bene anche nell'altro modo.
cortecce

153

Il formato PNG ha il supporto per metadati più o meno arbitrari. Lo standard PNG definisce un file PNG, essenzialmente una serie di blocchi, alcuni dei quali sono richiesti (e contengono i dati dell'immagine). Altri, tuttavia, sono opzionali. Ad esempio, esiste un blocco per la memorizzazione delle informazioni gamma o dei dati dell'istogramma.

In particolare, esiste un tEXtblocco che può essere utilizzato per memorizzare coppie di testo chiave / valore arbitrarie. Questo può essere usato per spedire qualsiasi tipo di dato arbitrario che desideri, a condizione che tu possa rappresentarlo come testo (che è abbastanza probabile).

Avrai bisogno di una libreria PNG che ti consenta di accedere e manipolare questi blocchi aggiuntivi (come la libreria di riferimento ), oppure dovrai scriverne uno tu stesso. Quindi si tratta solo di scegliere come codificare i dati desiderati come coppie chiave / valore. Suggerirei quanto segue:

  • scegli i nomi chiave che sono preceduti dal nome del tuo progetto o dal nome in codice come un modo per creare un sistema "namespace" grezzo ed evita potenziali conflitti con gli usi dei dati di altre applicazioni
  • non tentare di memorizzare trame reali in questo modo, memorizzare riferimenti a quelle trame che puntano all'interno del database delle risorse del gioco
  • dati come dimensioni di creature o oggetti, peso, eccetera - semplici scalari, in sostanza - possono essere archiviati banalmente

Nell'interesse di dare una risposta più completa, farò anche notare che esiste un altro approccio (precedentemente documentato dalle risposte di @Vaughn e @ Alexis): codificare i dati aggiuntivi desiderati direttamente nei pixel dell'immagine, distribuendo i dati attraverso i bit di ordine inferiore dei canali di colore. Questo approccio non richiede l'uso di metadati extra, il che significa che è possibile implementarlo interamente senza fare affidamento su di esso o preoccuparsi di programmi esterni che gestiscono in modo errato quei metadati. Ha anche un fattore "cool" molto alto, e poiché usi solo bit di basso ordine, l'immagine apparirà comunque corretta per l'occhio umano. Tuttavia, ciò significa che la dimensione dell'immagine è un fattore di controllo primario per la quantità di dati che è possibile memorizzare; se hai bisogno di più spazio di archiviazione, devi assegnare più pixel all'immagine.

Come altri hanno sottolineato, questo processo è noto come steganografia .


3
Si potrebbe semplicemente inviare i dati tramite Base64 e archiviarli come valore singolo
CodesInChaos

11
@ da4c30ff Pratica quanto i metadati, la steganografia ha un certo fattore cool di spionaggio e fantasia a cui è difficile resistere alla nostra folla. Se stessi facendo questo da solo, utilizzerei il metodo proposto di Josh Petrie per la scalabilità, ma sarei fortemente tentato di usare la steganografia per nascondere un checksum nell'immagine stessa per verificare che l'immagine e il testo appartengano l'uno all'altro - non perché questo è utile o sicuro, ma solo perché è bello. ;)
DMGregory

Cosa significa esattamente "testo" qui? Solo ASCII (carattere <= 127)? Qualsiasi byte tranne 0? Qualche byte? O qualcos'altro? (Ciò influirà sulla codifica che devi usare per scrivere dati binari. Ad esempio se hai bisogno di base64 o meno.)
svick

1
Ho aggiornato la risposta con un collegamento allo standard per il blocco di testo; ma sostanzialmente, il testo viene interpretato secondo ISO 8859-1 (caratteri a 8 bit, a byte singolo, latino-1).
Josh

51

Lo sviluppatore di Monaco in realtà ha fatto un eccellente articolo su come sia loro che Spore hanno realizzato questo.

Il riassunto di base di ciò che fanno è abbastanza semplice:

  • Converti i tuoi dati in binari
  • Converti l'immagine di destinazione in una bitmap non elaborata
  • Cammina lungo i pixel dell'immagine in modo prevedibile (semplicemente fanno da sinistra a destra dall'angolo in alto a sinistra).
  • Scrivi un bit nel bit di ordine più basso di ciascun canale di colore di ciascun pixel
  • Esporta nuovamente la bitmap modificata in png

Basta farlo al contrario per recuperare i tuoi dati.

L'idea alla base del processo è che ci sono molti pixel in un'immagine e i bit di ordine più basso di ciascun canale di colore non fanno una grande differenza. Inoltre, circa la metà dei bit che scrivi sarà esattamente quello che era già il bit nell'immagine. Quello che ottieni è essenzialmente l'immagine giusta, ma con strani artefatti. Prende tempo per notare che questi artefatti sono davvero evidenti solo se si mette in moto il contrasto / saturazione e lo zoom in avanti. Tuttavia, ha immagini sorgente con un sacco di rumore iniziale.

Dall'articolo:

Si noti nell'ultima immagine come c'è una linea orizzontale appena percettibile nel rumore. Questa è la fine dei dati di livello. Ciò significa che posso effettivamente adattare tutti i dati di livello in un'immagine di 265x120 pixel, usando solo il bit meno significativo.

UN TRENDY ADDENDUM:

Qualcosa che potrei fare e credo che anche la gente di Spore abbia usato TUTTO i bit di colore in pixel trasparenti al 100%. Dato che quei pixel sono trasparenti, non importa quale colore li imposti.

Non posso farlo, tuttavia, poiché sto usando l'intera immagine, il che significa che non ho pixel trasparenti con cui lavorare.

Perché preferire questa tecnica semplicemente memorizzandola nei metadati?

  • È più divertente! :)
  • I servizi possono manipolare i metadati (possibilmente come una funzione di privacy / sicurezza), ma non dovrebbero manipolare i pixel del tuo png a meno che non abbiano requisiti aggressivi di hosting delle immagini (ti guardano, Facebook). Ma se stanno riesportando completamente la tua immagine, non c'è nulla che tu possa fare in modo affidabile .

Credito extra: per ridurre la notevole rumorosità, è possibile utilizzare un PRNG con seme fisso per selezionare i pixel da modificare. È inoltre possibile modificare solo alcuni dei canali di colore in modo simile.


6
Esistono algoritmi steganografici più robusti rispetto al ridimensionamento delle immagini / alla regolazione del colore rispetto al metodo Monaco. (Anche se in genere memorizzano i dati a una densità sostanzialmente inferiore) Un esempio è la filigrana utilizzata negli screenshot di World of Warcraft: ownedcore.com/forums/world-of-warcraft/…
DMGregory

@DMGregory Nice find! L'algoritmo preciso che scegli dovrebbe ovviamente essere deciso dalla tua specifica base (spazio, durata, segretezza, ecc.).
Alexis Beingessner,

1
Per quanto possa sembrare bello, è una cattiva idea. Le immagini PNG usano la compressione delle immagini senza perdita ; armeggiare con i bit bassi dell'immagine renderà probabilmente il file più grande allo stesso tempo in quanto (leggermente) riduce la qualità dell'immagine. Assolutamente qualsiasi informazione può essere codificata come "testo", quindi usare un blocco di metadati è il modo ovviamente corretto per farlo; qualcuno che armeggia i bit di immagine senza realmente aver bisogno della steganografia è solo impennate.
Dfeuer,

1
@dfeuer - Apparentemente sia Spore che Monaco stavano usando framework di gioco che hanno una pipeline di caricamento delle risorse che riduce il .PNG in una bitmap, quindi i blocchi di metadati non ce la facevano.
Russell Borogove,

1
@dfeuer Ho fatto alcuni test ingenui. L'approccio con metadati sembra aggiungere circa l'80% della dimensione aggiunta dall'approccio stenografico quando si scrivono 100kB di bit casuali su un'immagine 1920x1080px. Testato su un'immagine vuota e uno screenshot del desktop. Non esattamente una differenza catastrofica, ma meatadata è sicuramente migliore (e più coerente) se sei davvero preoccupato per oltre 40kB. Si noti che i metadati erano ancora piuttosto inefficienti. Ho guadagnato 181kB per aver scritto 100kB di dati! Potrebbe essere spazio per ottimizzare il modo in cui la stringa è codificata o qualcosa del genere.
Alexis Beingessner,

7

Ho scaricato ed esaminato alcune creature di Spore da Sporepedia. Da quelli che ho imparato che:

  • Le immagini non contengono informazioni oltre ai dati di immagine standard.
  • I dati stenografici sono stati archiviati senza alcuna considerazione per l'immagine, si potrebbe immaginare che le parti trasparenti siano state utilizzate esclusivamente, ma non lo sono.
  • L'uso dell'archiviazione dipende dalla quantità di informazioni che devono essere archiviate, alcune delle immagini hanno usato solo il bit meno significativo per l'archiviazione dei dati, alcune hanno usato i due bit meno significativi, altre potrebbero usarne di più.
  • Il formato Spore evita di utilizzare un bit solo su una parte dell'immagine, il bit meno significativo cambia in tutta l'immagine, se viene utilizzato il secondo bit meno significativo, viene utilizzato sull'intera immagine. Questo è presumibilmente fatto usando un'imbottitura casuale. Questo evita un cambiamento di qualità che potrebbe essere più inquietante per lo spettatore rispetto al rumore stesso.
  • Tutti e quattro i canali sono usati allo stesso modo, il canale di opacità non ha un trattamento speciale, quindi alcuni dei pixel trasparenti sono leggermente opachi mentre alcuni dei pixel opachi sono leggermente trasparenti.

Vale la pena notare che questo è proprio ciò che fa Spore, è un metodo che mette la semplicità davanti alla maggior parte delle altre preoccupazioni.

La scelta di utilizzare la stenografia piuttosto che un blocco dati aggiuntivo significa che i dati sopravvivranno se l'immagine viene ricodificata, ad esempio da un sito Web, anche se non sopravviverà al ridimensionamento o alla compressione Jpeg.

Penso che l'alternativa più importante sia in realtà quella di codificare solo un ID nell'immagine e lasciare che i dati effettivi vengano archiviati su un server centrale dove questo ID può essere scambiato con i dati esatti della creatura. Un tale ID sarebbe abbastanza breve da poter essere codificato in un formato stenografico tollerante in scala e compressione.

Possibili semplici miglioramenti al formato Spore includono:

  • Usa solo o preferisci usare i valori di colore dei pixel trasparenti, non fanno differenza visiva.
  • Usa di più il canale blu e meno il canale verde, il colore blu ha un impatto percepito inferiore sull'immagine.
  • Mantenendo invariata la luminanza di ciascun pixel e codificando i dati in chroma, un po 'di rumore in questo parametro è praticamente non rilevabile per l'uomo.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.