Se un'immagine vale 1000 parole, quanto di un'immagine puoi inserire in 140 caratteri?
Nota : è tutto gente! La scadenza di Bounty è arrivata e, dopo alcune difficili deliberazioni, ho deciso che l'ingresso di Boojum ha appena cancellato quello di Sam Hocevar . Pubblicherò note più dettagliate una volta che avrò avuto la possibilità di scriverle. Ovviamente, tutti dovrebbero sentirsi liberi di continuare a presentare soluzioni e migliorare soluzioni su cui le persone possano votare. Grazie a tutti coloro che hanno inviato e iscritto; Mi sono piaciute tutte. È stato molto divertente per me correre e spero sia divertente sia per i partecipanti che per gli spettatori.
Mi sono imbattuto in questo interessante post sul tentativo di comprimere le immagini in un commento su Twitter e molte persone in quel thread (e un thread su Reddit ) avevano suggerimenti su diversi modi in cui potresti farlo. Quindi, immagino che sarebbe una buona sfida per la programmazione; lascia che le persone mettano i loro soldi dov'è la loro bocca e mostra come le loro idee sulla codifica possono portare a maggiori dettagli nello spazio limitato che hai a disposizione.
Ti sfido a inventare un sistema generico per codificare le immagini in messaggi Twitter di 140 caratteri e decodificarle di nuovo in un'immagine. Puoi usare i caratteri Unicode, in modo da ottenere più di 8 bit per carattere. Anche tenendo conto dei caratteri Unicode, tuttavia, dovrai comprimere le immagini in una quantità molto piccola di spazio; questa sarà sicuramente una compressione con perdita di dati, e quindi ci dovranno essere giudizi soggettivi sulla bontà di ogni risultato.
Ecco il risultato che l'autore originale, Quasimondo , ha ottenuto dalla sua codifica (l'immagine è sotto licenza Creative Commons Attribution-Non commercial commercial ):
Puoi fare di meglio?
Regole
- Il tuo programma deve avere due modalità: codifica e decodifica .
- Durante la codifica :
- Il tuo programma deve prendere come input un elemento grafico in qualsiasi formato grafico raster di tua scelta. Diremo che qualsiasi formato raster supportato da ImageMagick viene considerato ragionevole.
- Il programma deve generare un messaggio che può essere rappresentato in 140 o meno punti di codice Unicode; 140 punti di codice nella gamma
U+0000
-U+10FFFF
, esclusi i non-personaggi (U+FFFE
,U+FFFF
,U+
nFFFE
,U+
nFFFF
dove n è1
-10
esadecimale, e la gammaU+FDD0
-U+FDEF
) e punti di codice surrogati (U+D800
-U+DFFF
). Può essere emesso in qualsiasi codifica ragionevole a tua scelta; qualsiasi codifica supportata da GNUiconv
sarà considerata ragionevole e la codifica nativa della piattaforma o la codifica locale sarebbe probabilmente una buona scelta. Vedi le note Unicode di seguito per maggiori dettagli.
- Durante la decodifica :
- Il tuo programma dovrebbe prendere come input l'output della tua modalità di codifica .
- Il tuo programma deve produrre un'immagine in qualsiasi formato ragionevole a tua scelta, come definito sopra, anche se per i formati vettoriali di output è OK.
- L'output dell'immagine dovrebbe essere un'approssimazione dell'immagine di input; più ci si avvicina all'immagine in ingresso, meglio è.
- Il processo di decodifica potrebbe non avere accesso a nessun altro output del processo di codifica diverso dall'output sopra specificato; vale a dire, non è possibile caricare l'immagine da qualche parte e generare l'URL per il processo di decodifica da scaricare o qualsiasi altra cosa sciocca.
Per motivi di coerenza nell'interfaccia utente, il programma deve comportarsi come segue:
- Il programma deve essere uno script che può essere impostato su eseguibile su una piattaforma con l'interprete appropriato o un programma che può essere compilato in un eseguibile.
- Il tuo programma deve prendere come primo argomento
encode
odecode
per impostare la modalità. Il programma deve ricevere input in uno o più dei seguenti modi (se si implementa quello che accetta i nomi di file, è anche possibile leggere e scrivere da stdin e stdout se mancano i nomi di file):
Prendi input dallo standard in e produce output allo standard out.
my-program encode <input.png >output.txt my-program decode <output.txt >output.png
Prendi l'input da un file chiamato nel secondo argomento e produce output nel file indicato nel terzo.
my-program encode input.png output.txt my-program decode output.txt output.png
- Per la tua soluzione, inserisci:
- Il tuo codice, per intero, e / o un link ad esso ospitato altrove (se è molto lungo, o richiede molti file da compilare, o qualcosa del genere).
- Una spiegazione di come funziona, se non è immediatamente evidente dal codice o se il codice è lungo e le persone saranno interessate a un riepilogo.
- Un'immagine di esempio, con l'immagine originale, il testo che comprime e l'immagine decodificata.
- Se stai sviluppando un'idea che aveva qualcun altro, ti preghiamo di attribuirli. Va bene provare a perfezionare l'idea di qualcun altro, ma devi attribuirli.
Linee guida
Queste sono fondamentalmente regole che possono essere infrante, suggerimenti o criteri di punteggio:
- L'estetica è importante. Giudicherò e suggerirò che altre persone giudichino, in base a:
- Quanto è buona l'immagine di output e quanto assomiglia all'originale.
- Com'è bello il testo. Gobbledigook completamente casuale va bene se hai uno schema di compressione davvero intelligente, ma voglio anche vedere le risposte che trasformano le immagini in poesie multilingue o qualcosa di intelligente. Si noti che l'autore della soluzione originale ha deciso di utilizzare solo caratteri cinesi, poiché sembrava più bello in quel modo.
- Il codice interessante e gli algoritmi intelligenti sono sempre buoni. Mi piacciono i codici brevi e chiari, ma gli algoritmi complicati davvero intelligenti vanno bene anche se producono buoni risultati.
- Anche la velocità è importante, anche se non tanto quanto la capacità di un lavoro di comprimere l'immagine. Preferirei avere un programma in grado di convertire un'immagine in un decimo di secondo rispetto a qualcosa che eseguirà algoritmi genetici per giorni e giorni.
- Preferirò soluzioni più brevi a soluzioni più lunghe, purché ragionevolmente comparabili in termini di qualità; la concisione è una virtù.
- Il tuo programma dovrebbe essere implementato in una lingua che ha un'implementazione liberamente disponibile su Mac OS X, Linux o Windows. Mi piacerebbe essere in grado di eseguire i programmi, ma se hai un'ottima soluzione che funziona solo con MATLAB o qualcosa del genere, va bene.
- Il tuo programma dovrebbe essere il più generale possibile; dovrebbe funzionare per il maggior numero possibile di immagini diverse, sebbene alcune possano produrre risultati migliori di altre. In particolare:
- Avere alcune immagini integrate nel programma a cui corrisponde e scrive un riferimento, e quindi produce l'immagine corrispondente dopo la decodifica, è abbastanza zoppo e coprirà solo alcune immagini.
- Un programma che può acquisire immagini di forme geometriche semplici, piatte e geometriche e scomporle in una primitiva vettoriale è piuttosto ingegnoso, ma se fallisce su immagini al di là di una certa complessità probabilmente non è sufficientemente generale.
- Un programma che può solo catturare immagini con un particolare formato fisso ma che fa un buon lavoro con loro sarebbe anche OK, ma non ideale.
- Potresti scoprire che un'immagine in bianco e nero può ottenere più informazioni in uno spazio più piccolo di un'immagine a colori. D'altra parte, ciò può limitare i tipi di immagine a cui è applicabile; i volti vengono bene in bianco e nero, ma i disegni astratti potrebbero non andare così bene.
- Va benissimo se l'immagine in uscita è più piccola dell'input, pur essendo all'incirca la stessa proporzione. Va bene se devi ridimensionare l'immagine per confrontarla con l'originale; l'importante è come appare.
- Il tuo programma dovrebbe produrre output che potrebbero effettivamente passare attraverso Twitter e uscirne incolumi. Questa è solo una linea guida piuttosto che una regola, dal momento che non sono riuscito a trovare alcuna documentazione sull'esatto set di caratteri supportati, ma probabilmente dovresti evitare i personaggi di controllo, i funky invisibili che combinano personaggi, i personaggi di uso privato e simili.
Rubrica del punteggio
Come guida generale su come classificherò le soluzioni nella scelta della mia soluzione accettata, supponiamo che probabilmente valuterò le soluzioni su una scala di 25 punti (questo è molto approssimativo e non segnerò nulla direttamente, usando solo questo come linea guida di base):
- 15 punti per quanto bene lo schema di codifica riproduca una vasta gamma di immagini di input. Questo è un giudizio estetico soggettivo
- 0 significa che non funziona affatto, restituisce la stessa immagine ogni volta o qualcosa del genere
- 5 significa che può codificare alcune immagini, anche se la versione decodificata sembra brutta e potrebbe non funzionare affatto su immagini più complicate
- 10 significa che funziona su una vasta gamma di immagini e produce immagini dall'aspetto piacevole che a volte possono essere distinguibili
- 15 significa che produce repliche perfette di alcune immagini e anche per immagini più grandi e complesse, dà qualcosa che è riconoscibile. O forse non rende le immagini abbastanza riconoscibili, ma produce bellissime immagini che sono chiaramente derivate dall'originale.
- 3 punti per un uso intelligente del set di caratteri Unicode
- 0 punti per usare semplicemente l'intero set di caratteri consentiti
- 1 punto per l'utilizzo di un set limitato di caratteri sicuri per il trasferimento su Twitter o in una più ampia varietà di situazioni
- 2 punti per l'utilizzo di un sottoinsieme tematico di personaggi, come solo ideogrammi Han o solo personaggi da destra a sinistra
- 3 punti per fare qualcosa di veramente pulito, come generare testo leggibile o usare caratteri che sembrano l'immagine in questione
- 3 punti per approcci algoritmici intelligenti e stile del codice
- 0 punti per qualcosa che è di 1000 righe di codice solo per ridimensionare l'immagine, trattarla come 1 bit per pixel e base64 codifica che
- 1 punto per qualcosa che utilizza una tecnica di codifica standard ed è ben scritto e breve
- 2 punti per qualcosa che introduce una tecnica di codifica relativamente nuova, o che è sorprendentemente breve e pulito
- 3 punti per un liner che in realtà produce buoni risultati o qualcosa che apre nuovi orizzonti nella codifica grafica (se questo sembra un numero basso di punti per l'apertura di nuovi terreni, ricorda che un risultato così buono avrà probabilmente un punteggio elevato per l'estetica anche)
- 2 punti per la velocità. A parità di altre condizioni, più veloce è meglio, ma i criteri di cui sopra sono tutti più importanti della velocità
- 1 punto per l'esecuzione su software libero (open source), perché preferisco il software libero (notare che C # sarà ancora idoneo per questo punto finché funziona su Mono, allo stesso modo il codice MATLAB sarebbe idoneo se funziona su GNU Octave)
- 1 punto per seguire effettivamente tutte le regole. Queste regole sono diventate un po 'grandi e complicate, quindi probabilmente accetterò altrimenti buone risposte che sbagliano un piccolo dettaglio, ma darò un punto in più a qualsiasi soluzione che segua effettivamente tutte le regole
Immagini di riferimento
Alcune persone hanno chiesto alcune immagini di riferimento. Ecco alcune immagini di riferimento che puoi provare; qui sono incorporate versioni più piccole, tutte collegate a versioni più grandi dell'immagine se ne hai bisogno:
Premio
Offro una ricompensa di 500 rappresentanti (più i 50 che StackOverflow mette in campo) per la soluzione che mi piace di più, sulla base dei criteri di cui sopra. Ovviamente, incoraggio tutti gli altri a votare anche qui le loro soluzioni preferite.
Nota sulla scadenza
Questo concorso durerà fino allo scadere della taglia, verso le 18:00 di sabato 30 maggio. Non posso dire l'ora esatta in cui finirà; potrebbe essere ovunque dalle 17 alle 19. Garantirò che esaminerò tutte le voci inviate entro le 14:00 e farò del mio meglio per esaminare tutte le voci inviate entro le 16:00; se le soluzioni vengono presentate dopo, potrei non avere la possibilità di dar loro un aspetto corretto prima di dover prendere la mia decisione. Inoltre, prima invii, più possibilità avrai di votare per aiutarmi a scegliere la soluzione migliore, quindi prova a inviare prima piuttosto che alla scadenza.
Note Unicode
C'è stata anche una certa confusione su cosa sono ammessi i caratteri Unicode. La gamma di possibili punti di codice Unicode è U+0000
a U+10FFFF
. Ci sono alcuni punti di codice che non sono mai validi da usare come caratteri Unicode in uno scambio di dati aperto; questi sono i non caratteri e i punti di codice surrogato . Noncharacters sono definiti nel Unidode standard 5.1.0 sezione 16.7 come i valori U+FFFE
, U+FFFF
, U+
nFFFE
, U+
nFFFF
dove n è 1
- 10
esadecimale, e la gamma U+FDD0
-U+FDEF
. Questi valori devono essere utilizzati per un uso interno specifico dell'applicazione e le applicazioni conformi possono rimuovere questi caratteri dal testo elaborato da essi. I punti di codice surrogato, definiti in Unicode Standard 5.1.0 sezione 3.8 come U+D800
- U+DFFF
, vengono utilizzati per codificare caratteri oltre il piano multilingue di base in UTF-16; pertanto, è impossibile rappresentare questi punti di codice direttamente nella codifica UTF-16 e non è valido codificarli in qualsiasi altra codifica. Pertanto, ai fini di questo concorso, io consentire a qualsiasi programma che codifica le immagini in una sequenza di non più di 140 punti di codice Unicode dalla gamma U+0000
- U+10FFFF
, escludendo tutti noncharacters e coppie di surrogati come definito sopra.
Io preferisco le soluzioni che utilizzano solo i caratteri assegnati, e quelli ancora migliori che utilizzano sottoinsiemi intelligenti di caratteri assegnati o fare qualcosa di interessante con il set di caratteri che utilizzano. Per un elenco di caratteri assegnati, consultare il database dei caratteri Unicode ; si noti che alcuni caratteri sono elencati direttamente, mentre altri sono elencati solo come l'inizio e la fine di un intervallo. Si noti inoltre che i punti di codice surrogato sono elencati nel database, ma è vietato come indicato sopra. Se desideri sfruttare alcune proprietà dei caratteri per rendere più interessante il testo che hai emesso, ci sono una varietà di database di informazioni sui caratteri disponibili, come un elenco di blocchi di codice con nome e varie proprietà dei caratteri.
Dal momento che Twitter non specifica il set di caratteri esatto che supportano, sarò indulgente riguardo alle soluzioni che in realtà non funzionano con Twitter perché alcuni caratteri contano di più o alcuni caratteri vengono eliminati. Si preferisce, ma non è necessario, che tutti gli output codificati possano essere trasferiti incolumi tramite Twitter o un altro servizio di microblogging come identi.ca . Ho visto alcuni documenti che affermano che Twitter entità codifica <,> e &, e quindi li conteggia rispettivamente come 4, 4 e 5 caratteri, ma non l'ho provato da solo, e il loro contatore di caratteri JavaScript non sembra contarli in quel modo.
Suggerimenti e collegamenti
- La definizione di caratteri Unicode validi nelle regole è un po 'complicata. La scelta di un singolo blocco di caratteri, come gli Ideografi unificati CJK (U + 4E00 – U + 9FCF), potrebbe essere più semplice.
- È possibile utilizzare librerie di immagini esistenti, come ImageMagick o Python Imaging Library , per la manipolazione delle immagini.
- Se hai bisogno di aiuto per comprendere il set di caratteri Unicode e le sue varie codifiche, consulta questa guida rapida o questa FAQ dettagliata su UTF-8 in Linux e Unix .
- Prima si ottiene la soluzione, più tempo io (e altre persone voteremo) dovrò esaminarla. È possibile modificare la soluzione se la si migliora; Baserò la mia taglia sulla versione più recente quando darò il mio ultimo sguardo alle soluzioni.
- Se vuoi analizzare e scrivere un semplice formato di immagine (e non vuoi semplicemente usare un formato esistente), ti suggerisco di utilizzare il formato PPM . È un formato basato su testo che è molto facile da lavorare e puoi usare ImageMagick per convertire da e verso di esso.