Pracuję nad programem, który pobiera ciąg znaków, przekształca każdy znak ciągu w kolor, a następnie rysuje kolory od lewej do prawej, od góry do dołu w poprzek obrazu. Obraz można następnie zdekodować, używając tego samego programu, aby odzyskać oryginalną wiadomość. Jako przykład, oto clojure.core
, zakodowany jako obraz:Kodowanie ciągu znaków jako obrazu powoduje kompresję
napisałem to tylko jako zabawka, ale zauważyłem ciekawą właściwość obrazów produkuje: są one mniejsze niż oryginalne komunikaty były jako tekst. Dla clojure.core
jest to 259 kB jako tekst, ale tylko 88,9 kB jako obraz (powyżej) (obie wartości to "rozmiar na dysku"). Aby upewnić się, że dane nie zostały utracone, dekodowałem obraz i odzyskałem oryginalną wiadomość.
Jak to jest możliwe? Myślę, że obraz (format png
) miałby nagłówki i inne dodatkowe informacje, które mogłyby zawyżać rozmiar.
Cały kod clojure.core
zawiera 265486 znaków (zgodnie z Notepad ++), co oznacza, że każda postać zajmuje po prostu bajt.
Po pracy z klasą BufferedImage
(Java) wygląda na to, że kolory są zapisywane jako 4-bajtowe liczby całkowite, więc czy nie każdy piksel wymaga ~ 4x pamięci?
Oto jak to zakodowane:
Pierwszy znak ciąg jest zdejmowana
To przekłada się na kolor przez coraz to wartość ASCII, mnożąc ją przez dużą liczbę (tak go lepiej pasuje do zakresu możliwych kolorów), następnie liczba ta jest konwertowana na 3-cyfrowy numer bazowy 256 (
[123 100 200]
).Każda cyfra jest traktowana jako kanały czerwony, zielony i niebieski, które są podawane w metodzie
BufferedImage
's za pomocą metody .Wskaźnik
position
jest zaawansowany, następny znak jest wstawiany, a proces powtarza się, aż cały komunikat zostanie zakodowany.
Algorytm jest teraz trochę zawiłowany. @Thumbnail zasugerował znacznie lepszy sposób przeglądania kodu, ale jeszcze go nie wdrożyłem. Ponieważ wyniki są takie same, nie powinno to mieć znaczenia dla pytania.
Mimo że odpowiedź była dość oczywista, nadal lubiłem czytać o twoich odkryciach. Zawsze fajnie jest spotkać takie rzeczy. –