Jeśli zdjęcie ma 1000 słów, ile można zmieścić w 140 znakach?
Uwaga : To wszystko ludzie! Termin nagrody jest już za nami i po trudnych naradach zdecydowałem, że wpis Boojuma ledwo wykoleił się przed Samem Hocevarem . Opublikuję bardziej szczegółowe notatki, gdy będę miał okazję je napisać. Oczywiście wszyscy powinni swobodnie przesyłać rozwiązania i ulepszać rozwiązania umożliwiające głosowanie. Dziękujemy wszystkim, którzy przesłali i zgłosili; Podobało mi się wszystkie. To była dla mnie świetna zabawa i mam nadzieję, że zarówno uczestnicy, jak i widzowie byli zadowoleni.
Natknąłem się na ten interesujący post o próbie kompresji obrazów w komentarz na Twitterze, a wiele osób w tym wątku (i wątku na Reddit ) miało sugestie dotyczące różnych sposobów, w jaki możesz to zrobić. Myślę więc, że byłoby to dobre wyzwanie w kodowaniu; pozwól ludziom wkładać pieniądze tam, gdzie są ich usta, i pokaż, w jaki sposób ich pomysły na temat kodowania mogą prowadzić do uszczegółowienia na ograniczonej przestrzeni, którą masz do dyspozycji.
Rzucam ci wyzwanie, abyś opracował system ogólnego przeznaczenia do kodowania obrazów w 140 znakowych wiadomościach na Twitterze i dekodowania ich ponownie w obraz. Możesz używać znaków Unicode, aby uzyskać więcej niż 8 bitów na znak. Jednak nawet uwzględniając znaki Unicode, będziesz musiał skompresować obrazy do bardzo małej ilości miejsca; będzie to z pewnością kompresja stratna, dlatego trzeba będzie subiektywnie oceniać, jak dobrze każdy wynik wygląda.
Oto wynik, który oryginalny autor Quasimondo uzyskał ze swojego kodowania (zdjęcie jest licencjonowane na licencji Creative Commons Uznanie autorstwa-Użycie niekomercyjne ):
Czy potrafisz lepiej?
Zasady
- Twój program musi mieć dwa tryby: kodowania i dekodowania .
- Podczas kodowania :
- Twój program musi przyjąć jako dane wejściowe grafikę w dowolnym rozsądnym wybranym formacie graficznym rastrowym . Powiemy, że każdy format rastrowy obsługiwany przez ImageMagick liczy się jako rozsądny.
- Twój program musi wyświetlić komunikat, który może być reprezentowany w 140 lub mniej punktach kodu Unicode; 140 punktów kodu w zakresie
U+0000
-U+10FFFF
, Z wyłączeniem znaków (U+FFFE
,U+FFFF
,U+
nFFFE
,U+
nFFFF
, gdzie n jest1
-10
szesnastkowym, a zakresU+FDD0
-U+FDEF
) i zastępcze punkty kodowe (U+D800
-U+DFFF
). Może być wyprowadzany w dowolnym rozsądnym wybranym kodowaniu; każde kodowanie obsługiwane przez GNUiconv
zostanie uznane za rozsądne, a kodowanie natywne platformy lub kodowanie regionalne prawdopodobnie będzie dobrym wyborem. Aby uzyskać więcej informacji, zobacz uwagi do Unicode poniżej.
- Podczas dekodowania :
- Twój program powinien pobierać dane wejściowe z trybu kodowania .
- Twój program musi wyprowadzać obraz w dowolnym rozsądnym formacie wybranym przez ciebie, jak określono powyżej, chociaż dla formatów wyjściowych wektorów również są OK.
- Obraz wyjściowy powinien być przybliżeniem obrazu wejściowego; im bliżej można dostać się do obrazu wejściowego, tym lepiej.
- Proces dekodowania może nie mieć dostępu do żadnych innych danych wyjściowych procesu kodowania innych niż dane wyjściowe określone powyżej; oznacza to, że nie można przesłać gdzieś obrazu i podać adresu URL procesu dekodowania do pobrania, ani niczego takiego głupiego.
W celu zachowania spójności interfejsu użytkownika program musi zachowywać się w następujący sposób:
- Twój program musi być skryptem, który można ustawić na wykonywalny na platformie za pomocą odpowiedniego interpretera, lub programem, który można skompilować w plik wykonywalny.
- Twój program powinien brać jako pierwszy argument albo
encode
czydecode
ustawienie trybu. Twój program musi pobierać dane wejściowe na jeden lub więcej z następujących sposobów (jeśli zaimplementujesz ten, który pobiera nazwy plików, możesz także czytać i zapisywać ze stdin i stdout, jeśli brakuje nazw plików):
Pobierz dane wejściowe ze standardowego wejścia i uzyskaj dane wyjściowe ze standardowego wyjścia.
my-program encode <input.png >output.txt my-program decode <output.txt >output.png
Pobierz dane wejściowe z pliku wymienionego w drugim argumencie i wygeneruj dane wyjściowe w pliku wymienionym w trzecim argumencie.
my-program encode input.png output.txt my-program decode output.txt output.png
- Dla swojego rozwiązania prosimy o opublikowanie:
- Twój kod w całości i / lub link do niego hostowany gdzie indziej (jeśli jest bardzo długi lub wymaga wielu plików do skompilowania, lub coś takiego).
- Wyjaśnienie, jak to działa, jeśli nie jest to bezpośrednio oczywiste z kodu lub jeśli kod jest długi, a ludzie będą zainteresowani podsumowaniem.
- Przykładowy obraz z oryginalnym obrazem, tekstem do którego jest skompresowany i zdekodowanym obrazem.
- Jeśli opierasz się na pomyśle, który miał ktoś inny, przypisz go. Możesz spróbować dopracować czyjś pomysł, ale musisz go przypisać.
Wytyczne
Są to w zasadzie reguły, które mogą zostać złamane, sugestie lub kryteria punktacji:
- Estetyka jest ważna. Będę oceniać i sugerować, aby inni ludzie osądzali na podstawie:
- Jak dobrze wygląda obraz wyjściowy i jak bardzo przypomina oryginał.
- Jak ładnie wygląda tekst. Całkowicie losowy gobbledigook jest OK, jeśli masz naprawdę sprytny schemat kompresji, ale chcę również zobaczyć odpowiedzi, które zamieniają obrazy w wielojęzyczne wiersze lub coś sprytnego. Zauważ, że autor oryginalnego rozwiązania zdecydował się używać tylko chińskich znaków, ponieważ w ten sposób wyglądał ładniej.
- Ciekawy kod i sprytne algorytmy są zawsze dobre. Lubię krótko, rzeczowo i przejrzysty kod, ale naprawdę sprytne, skomplikowane algorytmy są OK, o ile dają dobre wyniki.
- Szybkość jest również ważna, choć nie tak ważna, jak dobra praca kompresuje obraz. Wolę mieć program, który może konwertować obraz w ciągu jednej dziesiątej sekundy, niż coś, co będzie działało algorytmy genetyczne przez wiele dni.
- Wolę krótsze rozwiązania niż dłuższe, o ile są one stosunkowo porównywalne pod względem jakości; zwięzłość jest zaletą.
- Twój program powinien być implementowany w języku, który ma swobodnie dostępną implementację w systemie Mac OS X, Linux lub Windows. Chciałbym móc uruchamiać programy, ale jeśli masz świetne rozwiązanie, które działa tylko pod MATLABem lub coś w tym stylu, to w porządku.
- Twój program powinien być jak najbardziej ogólny; powinien działać na jak najwięcej różnych obrazów, chociaż niektóre mogą dawać lepsze wyniki niż inne. W szczególności:
- Posiadanie kilku obrazów wbudowanych w program, do którego pasuje i zapisuje odniesienie, a następnie po zdekodowaniu tworzy pasujący obraz, jest dość kulawe i obejmie tylko kilka obrazów.
- Program, który może robić zdjęcia prostych, płaskich, geometrycznych kształtów i rozkładać je na prymitywny wektor, jest całkiem sprytny, ale jeśli zawodzi na obrazach o określonej złożoności, prawdopodobnie nie jest wystarczająco ogólny.
- Program, który może robić zdjęcia tylko o określonym stałym współczynniku proporcji, ale wykonuje z nimi dobrą robotę, również byłby OK, ale nie idealny.
- Może się okazać, że obraz czarno-biały może uzyskać więcej informacji na mniejszej przestrzeni niż obraz kolorowy. Z drugiej strony może to ograniczać rodzaje obrazów, których dotyczy; twarze wyglądają dobrze w czerni i bieli, ale abstrakcyjne wzory mogą nie wyglądać tak dobrze.
- Jest całkowicie w porządku, jeśli obraz wyjściowy jest mniejszy niż wejście, przy mniej więcej takiej samej proporcji. W porządku, jeśli musisz przeskalować obraz w celu porównania z oryginałem; ważne jest, jak to wygląda.
- Twój program powinien generować dane wyjściowe, które mogłyby faktycznie przejść przez Twitter i wyjść bez szwanku. Jest to jedynie wytyczna, a nie reguła, ponieważ nie mogłem znaleźć żadnej dokumentacji na temat obsługiwanego dokładnego zestawu znaków, ale prawdopodobnie powinieneś unikać znaków kontrolnych, funky niewidocznych łączących znaki, znaków prywatnych i tym podobnych.
Punktacja rubryki
Jako ogólny przewodnik po tym, jak będę oceniać rozwiązania przy wyborze zaakceptowanego rozwiązania, powiedzmy, że prawdopodobnie będę oceniać rozwiązania w 25-punktowej skali (jest to bardzo szorstkie i nie będę oceniać niczego bezpośrednio, po prostu używając to jako podstawowa wytyczna):
- 15 punktów za to, jak dobrze schemat kodowania odtwarza szeroki zakres obrazów wejściowych. To subiektywny, estetyczny osąd
- 0 oznacza, że w ogóle nie działa, za każdym razem zwraca ten sam obraz lub coś w tym rodzaju
- 5 oznacza, że może zakodować kilka obrazów, chociaż dekodowana wersja wygląda brzydko i może nie działać w ogóle na bardziej skomplikowanych obrazach
- 10 oznacza, że działa na szerokiej gamie obrazów i tworzy przyjemnie wyglądające obrazy, które czasami mogą być rozpoznawalne
- 15 oznacza, że tworzy doskonałe repliki niektórych obrazów, a nawet w przypadku większych i bardziej złożonych obrazów daje coś, co można rozpoznać. A może nie tworzy obrazów, które są całkiem rozpoznawalne, ale tworzy piękne obrazy, które wyraźnie pochodzą z oryginału.
- 3 punkty za sprytne użycie zestawu znaków Unicode
- 0 punktów za zwykłe użycie całego zestawu dozwolonych znaków
- 1 punkt za użycie ograniczonego zestawu znaków, które można bezpiecznie przesyłać przez Twitter lub w wielu różnych sytuacjach
- 2 punkty za korzystanie z podzbioru tematycznego, takiego jak tylko ideogramy Hana lub tylko postacie od prawej do lewej
- 3 punkty za zrobienie czegoś naprawdę porządnego, na przykład wygenerowanie czytelnego tekstu lub użycie znaków, które wyglądają jak dany obraz
- 3 punkty za sprytne podejście algorytmiczne i styl kodu
- 0 punktów za coś, co zawiera 1000 linii kodu tylko w celu zmniejszenia skali obrazu, traktowania go jako 1 bit na piksel, a kodowanie base64 to
- 1 punkt za coś, co wykorzystuje standardową technikę kodowania, jest dobrze napisane i krótkie
- 2 punkty za coś, co wprowadza stosunkowo nową technikę kodowania lub jest zaskakująco krótkie i czyste
- 3 punkty za jedną linijkę, która faktycznie daje dobre wyniki, lub coś, co przełamuje nowy grunt w kodowaniu grafiki (jeśli wydaje się, że to mała liczba punktów za przełamanie nowej płaszczyzny, pamiętaj, że wynik tego dobra będzie prawdopodobnie miał wysoką ocenę za estetykę także)
- 2 punkty za prędkość. Gdy wszystko inne jest równe, szybsze jest lepsze, ale wszystkie powyższe kryteria są ważniejsze niż prędkość
- 1 punkt za uruchomienie na wolnym oprogramowaniu (open source), ponieważ wolę wolne oprogramowanie (pamiętaj, że C # będzie nadal kwalifikował się do tego punktu, dopóki będzie działał na Mono, podobnie kod MATLAB byłby kwalifikowany, gdyby działał na GNU Octave)
- 1 punkt za faktyczne przestrzeganie wszystkich zasad. Te zasady stały się nieco duże i skomplikowane, więc prawdopodobnie zaakceptuję dobre odpowiedzi, które pomylą jeden mały szczegół, ale dam dodatkowy punkt każdemu rozwiązaniu, które faktycznie spełnia wszystkie zasady
Obrazy referencyjne
Niektórzy ludzie prosili o obrazy referencyjne. Oto kilka obrazów referencyjnych, które możesz wypróbować; osadzone są tutaj mniejsze wersje, wszystkie prowadzą do większych wersji obrazu, jeśli potrzebujesz:
Nagroda
Oferuję nagrodę w wysokości 500 powtórzeń (plus 50, które uruchamia StackOverflow) za rozwiązanie, które lubię najbardziej, w oparciu o powyższe kryteria. Oczywiście zachęcam wszystkich innych do głosowania również na ich ulubione rozwiązania.
Uwaga na termin
Konkurs potrwa, dopóki nagroda się nie skończy, około 18:00 w sobotę 30 maja. Nie mogę powiedzieć, kiedy dokładnie się skończy; może być w dowolnym miejscu od 17:00 do 19:00. Gwarantuję, że przejrzę wszystkie zgłoszenia przesłane do 14.00 i dołożę wszelkich starań, aby zobaczyć wszystkie zgłoszenia przesłane do 16:00; jeśli później zostaną przedstawione rozwiązania, może nie będę miał szansy rzucić im sprawiedliwego spojrzenia, zanim będę musiał podjąć decyzję. Ponadto, im wcześniej prześlesz, tym większa szansa, że będziesz mieć możliwość głosowania, aby pomóc mi wybrać najlepsze rozwiązanie, więc spróbuj przesłać je wcześniej niż w wyznaczonym terminie.
Notatki Unicode
Nastąpiło również pewne zamieszanie co do tego, jakie dokładnie znaki Unicode są dozwolone. Zakres możliwych punktów kodowych Unicode jest U+0000
do U+10FFFF
. Istnieją pewne punkty kodowe, których nigdy nie można używać jako znaków Unicode w dowolnej otwartej wymianie danych; są to znaki niebędące znakami i punkty kodu zastępczego . Noncharacters zdefiniowano w Unidode standardowa 5.1.0 16,7 części jako wartości U+FFFE
, U+FFFF
, U+
nFFFE
, U+
nFFFF
, gdzie n jest 1
- 10
szesnastkowym, a zakres U+FDD0
-U+FDEF
. Wartości te są przeznaczone do użytku wewnętrznego specyficznego dla aplikacji, a zgodne aplikacje mogą usunąć te znaki z przetwarzanego przez nich tekstu. Zastępcze punkty kodowe, zdefiniowane w Unicode Standard 5.1.0 sekcja 3.8 jako U+D800
- U+DFFF
, są używane do kodowania znaków poza podstawową płaszczyzną wielojęzyczną w UTF-16; dlatego niemożliwe jest reprezentowanie tych punktów kodowych bezpośrednio w kodowaniu UTF-16, a kodowanie ich w jakimkolwiek innym kodowaniu jest nieprawidłowe. Dlatego na potrzeby tego konkursu zezwalam na dowolny program, który koduje obrazy w sekwencji nie więcej niż 140 punktów kodu Unicode z zakresu U+0000
- z U+10FFFF
wyłączeniem wszystkich znaków niebędących znakami i par zastępczych, jak zdefiniowano powyżej.
Ja preferuję rozwiązań, które wykorzystują tylko przypisanych znaków, a nawet lepsze te, które wykorzystują sprytnych podzbiory przypisanych znaków lub zrobić coś ciekawego z zestawu znaków, których używają. Aby uzyskać listę przypisanych znaków, zobacz bazę znaków znaków Unicode ; zwróć uwagę, że niektóre znaki są wymienione bezpośrednio, a niektóre tylko na początku i na końcu zakresu. Należy również pamiętać, że punkty kodu zastępczego są wymienione w bazie danych, ale są zabronione, jak wspomniano powyżej. Jeśli chcesz skorzystać z niektórych właściwości znaków, aby tekst był bardziej interesujący, istnieje wiele baz danych z informacjami o znakach , takich jak lista nazwanych bloków kodu i różne właściwości znaków.
Ponieważ Twitter nie określa dokładnego zestawu znaków, które obsługują, nie będę tolerować rozwiązań, które w rzeczywistości nie działają z Twitterem, ponieważ niektóre znaki liczą dodatkowe lub niektóre znaki są usuwane. Preferowane jest, ale nie wymagane, aby wszystkie zakodowane wyjścia mogły być przesyłane bez szwanku przez Twitter lub inną usługę mikroblogowania, taką jak identi.ca . Widziałem trochę dokumentacji stwierdzającej, że encje Twittera kodują <,> i &, i dlatego liczą je odpowiednio jako 4, 4 i 5 znaków, ale sam tego nie przetestowałem, a ich licznik znaków JavaScript nie wydaje się policzyć je w ten sposób.
Wskazówki i linki
- Definicja prawidłowych znaków Unicode w regułach jest nieco skomplikowana. Wybór pojedynczego bloku znaków, takiego jak CJK Unified Ideographs (U + 4E00 – U + 9FCF) może być łatwiejszy.
- Do manipulacji obrazami możesz używać istniejących bibliotek obrazów, takich jak ImageMagick lub Python Imaging Library .
- Jeśli potrzebujesz pomocy w zrozumieniu zestawu znaków Unicode i jego różnych kodowań, zapoznaj się z tym krótkim przewodnikiem lub szczegółowymi często zadawanymi pytaniami na temat UTF-8 w systemach Linux i Unix .
- Im wcześniej dostaniesz swoje rozwiązanie, tym więcej czasu będę musiał (ja i inne osoby) głosować na to. Możesz edytować swoje rozwiązanie, jeśli je ulepszysz; Opłacę moją nagrodę za najnowszą wersję, kiedy po raz ostatni przejrzę rozwiązania.
- Jeśli chcesz, aby prosty format obrazu był analizowany i zapisywany (i nie chcesz po prostu używać istniejącego formatu), sugeruję użycie formatu PPM . Jest to format tekstowy, który jest bardzo łatwy w obsłudze, i możesz użyć ImageMagick do konwersji do iz niego.