Jak mogę przechowywać metadane gry w pliku .png?

208

Spore umożliwia udostępnianie stworzonych przez gracza stworzeń poprzez eksport .pngpliku. To .pngjest zdjęcie stworzenia, ale jeśli zostanie zaimportowane do gry, informacje o stworzeniu (takie jak tekstury, rozmiar i kształt) również będą z nim związane.

Jak mogę wdrożyć taką funkcję?

ibrabeicker
źródło
5
Powinien mieć znacznie wyższy wynik, to bardzo interesujące pytanie.
Pierre Arlaud,
3
Kanał alfa może być częściowo wykorzystany w tym celu ...
Tobias Kienzler,
3
Możliwe wykorzystanie: stackoverflow.com/questions/9542359/…
jednostka logiczna
1
Myślę, że lepiej przechowywać te dane w innym pliku. W tym pliku powinna znajdować się nazwa pliku tekstury powiązanego z jednostką, w której chcesz przechowywać dane. Po pierwsze ze względu na przejrzystość (format png jest przeznaczony do grafiki - „Portable Network Graphics”), po drugie: rozważ sytuację, w której chciałbyś przechowywać więcej obrazów z jednostką, możesz po prostu dodać do niej odniesienia z tego pliku niestandardowego. Prawdopodobnie będziesz mieć problem z przechowywaniem różnych obrazów (różnej wielkości, różnej głębokości itp.) W jednym pliku PNG.
luke1985
3
Kanał alfa został bardzo mocno wspomniany i oczywiście PNG i tak obsługują metadane, ale pomyślałem, że podzielę się techniką, której użyłem - przechodząc od lewej do prawej, od góry do dołu i przez kanały w ustalonej kolejności i zaokrąglanie wartości do kursów lub wyrównanych - nie ma znaczenia, czy jest to w górę, czy w dół. Zmiana 1 w ŻADNYM z kanałów nie robi zauważalnej różnicy, a na obrazie 256 x 256 (przy 4 bitach na piksel oczywiście) można przechowywać imponujące 32 KB danych. Jeśli potrzebujesz jeszcze więcej, możesz zamiast tego zaokrąglić do% 4 - za dużo i zaczyna wyglądać jak stary umysł GIF.
Octopoid

Odpowiedzi:

56

Jeśli wszystko, czego naprawdę potrzebujesz, to plik PNG, są szanse, że po prostu dodają informacje do pliku. To właściwie praktyka steganografii . Często służy to do ukrywania ładunków lub tajnych wiadomości w rzeczach, które wydają się publicznie dostępne. Jest jednak prawdopodobne, że w tym przypadku zastosowano tę metodę. Typowa Stegongraphy zejdzie z drogi, aby ukryć zawartość, ale nie ma powodu, dla którego nie można po prostu dodać danych z obrazu na końcu pliku i pobrać.

Kilka narzędzi koduje te dane dla Ciebie, wyszukiwarka Google przywołuje przynajmniej to i to .

PNG ma sygnaturę bajtu $89na początku, więc możliwe jest, że informacja została wstawiona za samą strukturą PNG i po prostu przeanalizowana przez grę SPORE.

Jednak dalsze badania podane przez inne odpowiedzi i wyszukiwanie w Google ujawniają, że Spore faktycznie używał tylko wersji Stegongraphy, aby ukryć informacje w bitach alfa. Mając to na uwadze, możemy wykluczyć możliwość dołączenia danych lub metadanych.

Należy zauważyć, że metadane są nadal bardzo realnym wyborem, jeśli dane są analizowane lokalnie. Jeśli te informacje mogą być udostępniane w Internecie lub ponownie kodowane, eksport nie gwarantuje zachowania wszystkich informacji. Gdy używane są dane w pikselach, mogą one bez problemu przetrwać konwersje bez strat.

Vaughan Hilts
źródło
3
O ile mi wiadomo, zarodniki przechowują metadane w kanale alfa PNG.
Tara
28
Po co korzystać z kanału alfa lub steganografii, gdy PNG obsługuje dowolne fragmenty metadanych?
Russell Borogove
8
„PNG ma na początku sygnaturę bajtu„ 89 ”, więc jest bardzo prawdopodobne, że informacja została wstawiona przed samą strukturą PNG lub po niej i po prostu przeanalizowana przez grę SPORE.” Gdyby tak było, to nie byłoby ” będzie już plikiem PNG. Tzn. Zwykłe przeglądarki obrazów nie byłyby w stanie go wyświetlić.
svick
3
@ RussellBorogove jeden dość dobry powód: jeśli PNG jest dekodowany / kodowany przez coś innego niż Spore, bardziej prawdopodobne jest, że dowolne fragmenty metadanych zostaną zignorowane lub utracone niż rzeczywiste dane obrazu. Kodowanie danych na obrazie zwiększa prawdopodobieństwo, że jeśli je zobaczysz, możesz je załadować .
Tim S.
@svick Właściwie grałem z plikiem, który był zarówno prawidłowym PNG, jak i RAR. Nagłówek RAR zaczął się po PNG, a ekstraktory RAR były w porządku. Może działać również w drugą stronę.
kora
153

PNG posiada wsparcie dla bardziej lub mniej arbitralnie metadanych. Standard PNG definiuje plik PNG, zasadniczo szereg fragmentów, z których niektóre są wymagane (i zawierają dane obrazu). Inne są jednak opcjonalne. Na przykład istnieje fragment do przechowywania informacji gamma lub danych histogramu.

W szczególności istnieje tEXtfragment, którego można użyć do przechowywania dowolnych par tekst / klucz. Można tego użyć do przesyłania dowolnych dowolnych danych, pod warunkiem, że możesz reprezentować te dane jako tekst (co jest całkiem prawdopodobne).

Będziesz potrzebował biblioteki PNG, która umożliwia dostęp i manipulowanie tymi dodatkowymi fragmentami (np. Biblioteką referencyjną ), lub będziesz musiał napisać jedną samodzielnie. Następnie wystarczy wybrać sposób kodowania danych jako pary klucz / wartość. Sugerowałbym następujące:

  • wybierz nazwy kluczy poprzedzone nazwą projektu lub nazwą kodową jako sposób tworzenia surowego systemu „przestrzeni nazw” i unikaj potencjalnych konfliktów z wykorzystaniem danych przez inne aplikacje
  • nie staraj się przechowywać rzeczywiste tekstur ten sposób przechowywać odnośniki do tych faktur, które wskazują w ramach własnej bazy aktywów swojej gry
  • dane takie jak rozmiar istoty lub obiektu, waga itp. - proste skalary, w zasadzie - mogą być trywialnie przechowywane

W celu uzyskania pełniejszej odpowiedzi zwrócę również uwagę na inne podejście (wcześniej udokumentowane odpowiedziami @Vaughn i @ Alexis): zakoduj dodatkowe dane, które chcesz bezpośrednio w pikselach obrazu, rozdzielając je między bity kanałów kolorów niskiego rzędu. Takie podejście nie wymaga użycia dodatkowych metadanych, co oznacza, że ​​można je całkowicie zaimplementować bez polegania na nich lub martwienia się, że programy zewnętrzne nieprawidłowo obsługują te metadane. Ma również bardzo wysoki współczynnik „cool”, a ponieważ używasz tylko bitów niskiego rzędu, obraz nadal będzie wyglądał poprawnie dla ludzkiego oka. Oznacza to jednak, że rozmiar obrazu jest głównym czynnikiem kontrolującym ilość danych, które można przechowywać; jeśli potrzebujesz więcej miejsca, musisz przydzielić więcej pikseli do obrazu.

Jak zauważyli inni, proces ten znany jest jako steganografia .

Josh
źródło
3
Można po prostu wysłać dane przez Base64 i zapisać je jako jedną wartość
CodesInChaos
11
@ da4c30ff Metadane są tak praktyczne, jak to, że steganografia ma pewien fajny czynnik szpiegowskiej fantazji, któremu trudno się oprzeć naszemu tłumowi. Gdybym to robił sam, użyłbym zaproponowanej przez Josha Petrie metody skalowalności, ale bardzo kusiło mnie użycie steganografii do ukrycia sumy kontrolnej na samym obrazie, aby sprawdzić, czy obraz i tekst należą do siebie - nie dlatego, że jest to przydatne lub bezpieczne, ale tylko dlatego, że jest fajne. ;)
DMGregory
Co dokładnie oznacza tutaj „tekst”? Tylko ASCII (znak <= 127)? Dowolny bajt oprócz 0? Jakieś bajty? Albo coś innego? (
Wpłynie
1
Zaktualizowałem odpowiedź linkiem do standardu dla fragmentu tekstu; ale w zasadzie tekst jest interpretowany zgodnie z ISO 8859-1 (8-bitowe, jednobajtowe znaki Latin-1).
Josh
51

Twórca Monako napisał świetny artykuł o tym, jak zarówno oni, jak i Spore to osiągnęli.

Podstawowe podsumowanie tego, co robią, jest dość proste:

  • Konwertuj swoje dane na pliki binarne
  • Przekształć obraz docelowy w surową mapę bitową
  • Przejdź wzdłuż pikseli obrazu w przewidywalny sposób (po prostu robią to od lewej do prawej od lewego górnego rogu).
  • Napisz jeden bit do bitu najniższego rzędu każdego kanału koloru każdego piksela
  • Wyeksportuj zmodyfikowaną bitmapę do png ponownie

Po prostu zrób to w odwrotnej kolejności, aby odzyskać swoje dane.

Podstawową ideą tego procesu jest to, że na obrazie jest dużo pikseli, a bity najniższego rzędu w każdym kanale kolorów nie mają większego znaczenia. Ponadto około połowa zapisanych bitów będzie tym, co bit na obrazie już był. To, co dostajesz, to właściwie właściwy obraz, ale z dziwnymi artefaktami. Poświęca trochę czasu, aby zauważyć, że te artefakty są naprawdę zauważalne tylko wtedy, gdy naprawdę zwiększysz kontrast / nasycenie i powiększysz. Ma jednak obrazy źródłowe z dużą ilością początkowego szumu.

Z artykułu:

Zwróć uwagę na ostatnim zdjęciu, jak w szumie jest ledwo dostrzegalna pozioma linia. To koniec danych poziomu. Oznacza to, że mogę dopasować wszystkie dane poziomu do obrazu 265 x 120 pikseli, używając tylko najmniej znaczącego bitu.

TRICKY DODATEK:

Coś, co mógłbym zrobić i uważam, że ludzie Spore również to zrobili, to w rzeczywistości użycie WSZYSTKICH bitów koloru w pikselach, które są w 100% przezroczyste. Ponieważ te piksele są przezroczyste, nie ma znaczenia, jaki kolor je ustawisz.

Nie mogę tego jednak zrobić, ponieważ używam całego obrazu, co oznacza, że ​​nie mam przezroczystych pikseli do pracy.

Po co faworyzować tę technikę niż tylko przechowywanie jej w metadanych?

  • Fajniej! :)
  • Usługi mogą zniekształcać metadane (być może jako funkcja prywatności / bezpieczeństwa), ale nie powinny zniekształcać pikseli twojego PNG, chyba że mają agresywne wymagania dotyczące hostingu obrazów (patrząc na ciebie, facebook). Ale jeśli są one całkowicie re-eksportu obraz nie ma nic Cię niezawodnie można zrobić.

Dodatkowy kredyt: aby zmniejszyć zauważalność szumu, możesz użyć PRNG ze stałym ziarnem, aby wybrać piksele do modyfikacji. Można również zmodyfikować tylko niektóre kanały kolorów w podobny sposób.

Alexis Beingessner
źródło
6
Istnieją algorytmy steganograficzne, które są bardziej odporne na skalowanie / dostosowanie kolorów niż metoda Monako. (Chociaż zazwyczaj przechowują dane o znacznie niższej gęstości) Jednym z przykładów jest znak wodny używany w zrzutach ekranu World of Warcraft: owncore.com/forums/world-of-warcraft/…
DMGregory
@DMGregory Ładne znalezisko! Dokładny algorytm, który wybierzesz, powinien oczywiście zależeć od konkretnego zastosowania (przestrzeń, trwałość, poufność itp.).
Alexis Beingessner,
1
Choć może to zabrzmi fajnie, to zły pomysł. Obrazy PNG używają bezstratnej kompresji obrazu ; błahy wokół z niskich bitów obrazu będzie prawdopodobnie sprawić, że plik większy w tym samym czasie, w którym (nieznacznie) obniża jakość obrazu. Absolutnie każda informacja może być zakodowana jako „tekst”, więc użycie fragmentu metadanych jest oczywiście poprawnym sposobem na zrobienie tego; ktoś majstrujący przy obrazach bez potrzeby steganografii po prostu rzuca kółkami.
dfeuer
1
@dfeuer - Najwyraźniej zarówno Spore, jak i Monaco korzystały ze struktur gier, które mają potok ładowania zasobów, który usuwa .PNG do samej mapy bitowej, więc fragmenty metadanych nie były w stanie przejść.
Russell Borogove
1
@dfeuer Zrobiłem kilka naiwnych testów. Metoda metadanych wydaje się dodawać około 80% wielkości dodanej przez metodę stenograficzną przy zapisywaniu 100 kB losowych bitów na obrazie o rozdzielczości 1920 x 1080 pikseli. Testowany na pustym obrazie i zrzucie ekranu pulpitu. Nie do końca katastroficzna różnica, ale meatadata jest z pewnością lepszy (i bardziej spójny), jeśli naprawdę martwisz się o ponad 40kB. Zauważ, że metadane wciąż były dość nieefektywne. Zyskałem 181kB za zapisanie 100kB danych! Może być miejsce na optymalizację sposobu kodowania łańcucha znaków lub coś w tym rodzaju.
Alexis Beingessner,
7

Pobrałem i zbadałem kilka stworzeń Spore ze Sporepedii. Od tych dowiedziałem się, że:

  • Obrazy nie zawierają żadnych informacji oprócz standardowych danych obrazu.
  • Dane stenograficzne zostały zapisane bez uwzględnienia obrazu, można sobie wyobrazić, że przezroczyste części zostały użyte wyłącznie, ale tak nie jest.
  • Wykorzystanie pamięci zależy od ilości informacji, które muszą być przechowywane, niektóre obrazy wykorzystują tylko najmniej znaczący bit do przechowywania danych, niektóre wykorzystują dwa najmniej znaczące bity, niektóre mogą zużywać więcej.
  • Format Spore pozwala uniknąć użycia bitu tylko na części obrazu, najmniej znaczący bit zmienia się w całym obrazie, jeśli użyty zostanie drugi najmniej znaczący bit, zostanie on użyty na całym obrazie. Można to zrobić za pomocą przypadkowego wypełnienia. Pozwala to uniknąć zmiany jakości, która może bardziej przeszkadzać widzowi niż sam hałas.
  • Wszystkie cztery kanały są używane jednakowo, kanał nieprzezroczystości nie jest poddawany specjalnej obróbce, dlatego niektóre przezroczyste piksele są lekko nieprzezroczyste, a niektóre nieprzezroczyste piksele są nieco przezroczyste.

Warto zauważyć, że to właśnie robi Spore, jest to metoda, która stawia prostotę przed większością innych obaw.

Wybór zastosowania stenografii zamiast dodatkowego bloku danych oznacza, że ​​dane przetrwają, jeśli obraz zostanie ponownie zakodowany, na przykład przez stronę internetową, chociaż nie przetrwa skalowania ani kompresji Jpeg.

Myślę, że najbardziej widoczną alternatywą jest zakodowanie tylko identyfikatora na obrazie i pozostawienie rzeczywistych danych na centralnym serwerze, gdzie ten identyfikator może zostać wymieniony na dokładne dane o stworzeniu. Taki identyfikator byłby wystarczająco krótki, aby można go było zakodować w formacie stenograficznym tolerującym skalowanie i kompresję.

Możliwe proste ulepszenia formatu Spore obejmują:

  • Używaj tylko lub wolisz używać wartości kolorów przezroczystych pikseli, nie mają one różnicy wizualnej.
  • Użyj niebieskiego kanału więcej, a zielonego mniej, niebieski kolor ma mniejszy wpływ na obraz.
  • Utrzymując luminancję każdego piksela blisko niezmienionego i kodując dane w barwie, niewielki szum w tym parametrze jest praktycznie niewykrywalny dla ludzi.
aaaaaaaaaaaa
źródło