Si une image vaut 1000 mots, quelle quantité d'image pouvez-vous faire tenir en 140 caractères ?
Note : C'est fini les gars ! La date limite pour le Bounty est arrivée, et après quelques délibérations difficiles, j'ai décidé que Entrée de Boojum a été devancé de justesse Sam Hocevar's . Je publierai des notes plus détaillées dès que j'aurai eu l'occasion de les rédiger. Bien sûr, chacun doit se sentir libre de continuer à soumettre des solutions et à les améliorer pour que les gens puissent voter. Merci à tous ceux qui ont soumis une participation ; je les ai tous appréciés. J'ai pris beaucoup de plaisir à organiser ce concours, et j'espère qu'il en a été de même pour les participants et les spectateurs.
Je suis tombé sur ce post intéressant à propos de la compression d'images dans un commentaire Twitter, et de nombreuses personnes dans ce fil de discussion (et une sur Reddit ) avait des suggestions sur les différentes façons de procéder. Je me suis donc dit que cela ferait un bon défi de codage ; laissez les gens joindre l'acte à la parole et montrer comment leurs idées sur le codage peuvent conduire à plus de détails dans l'espace limité dont vous disposez.
Je vous mets au défi de trouver un système général permettant de coder des images dans des messages Twitter de 140 caractères et de les décoder en une image. Vous pouvez utiliser les caractères Unicode, ce qui vous permet d'obtenir plus de 8 bits par caractère. Cependant, même en tenant compte des caractères Unicode, vous devrez comprimer les images dans un espace très réduit ; il s'agira certainement d'une compression avec perte, et il faudra donc porter un jugement subjectif sur la qualité de chaque résultat.
Voici le résultat que l'auteur original a obtenu, Quasimondo de son encodage (l'image est protégée par une licence de Licence Creative Commons Attribution-Non Commerciale ) :
Pouvez-vous faire mieux ?
Règles
-
Votre programme doit avoir deux modes : codage et décodage .
-
Lorsque codage :
- Votre programme doit prendre en entrée un graphique dans n'importe quel format raisonnable. trame format graphique de votre choix. Nous dirons que tout format matriciel pris en charge par ImageMagick compte comme raisonnable.
- Votre programme doit produire un message qui peut être représenté par 140 points de code Unicode ou moins ; 140 points de code dans la plage suivante
U+0000
-U+10FFFF
à l'exclusion des non caractères (U+FFFE
,U+FFFF
,U+
nFFFE
,U+
nFFFF
où n est1
-10
hexadécimal, et la plageU+FDD0
-U+FDEF
) et les points de code de substitution (U+D800
-U+DFFF
). Il peut être édité dans n'importe quel encodage raisonnable de votre choix ; tout encodage supporté par GNUiconv
sera considéré comme raisonnable, et l'encodage natif de votre plateforme ou l'encodage local sera probablement un bon choix. Voir Notes sur l'Unicode ci-dessous pour plus de détails.
-
Lorsque décodage :
- Votre programme devrait prendre comme entrée la sortie de votre codage mode.
- Votre programme doit produire une image dans le format raisonnable de votre choix, tel que défini ci-dessus, bien que les formats vectoriels soient également acceptables.
- L'image de sortie doit être une approximation de l'image d'entrée ; plus vous pouvez vous rapprocher de l'image d'entrée, mieux c'est.
- Le processus de décodage ne peut avoir accès à aucune autre sortie du processus de codage que celle spécifiée ci-dessus ; autrement dit, vous ne pouvez pas télécharger l'image quelque part et envoyer l'URL pour que le processus de décodage la télécharge, ou quelque chose de stupide de ce genre.
-
Pour des raisons de cohérence de l'interface utilisateur, votre programme doit se comporter comme suit :
- Votre programme doit être un script qui peut être défini comme exécutable sur une plate-forme dotée de l'interpréteur approprié, ou un programme qui peut être compilé en un exécutable.
- Votre programme doit prendre comme premier argument soit
encode
oudecode
pour régler le mode. -
Votre programme doit prendre en entrée une ou plusieurs des manières suivantes (si vous implémentez celle qui prend les noms de fichiers, vous pouvez également lire et écrire à partir de stdin et stdout si les noms de fichiers sont manquants) :
-
Prendre l'entrée d'une norme d'entrée et produire la sortie d'une norme de sortie.
my-program encode <input.png >output.txt my-program decode <output.txt >output.png
-
Prendre l'entrée d'un fichier nommé dans le deuxième argument, et produire la sortie dans le fichier nommé dans le troisième.
my-program encode input.png output.txt my-program decode output.txt output.png
-
-
Pour votre solution, veuillez poster :
- Votre code, dans son intégralité, et/ou un lien vers celui-ci hébergé ailleurs (s'il est très long, ou nécessite de nombreux fichiers à compiler, ou autre).
- Une explication de son fonctionnement, si cela n'est pas immédiatement évident à partir du code ou si le code est long et que les gens seront intéressés par un résumé.
- Un exemple d'image, avec l'image originale, le texte qu'elle compresse, et l'image décodée.
- Si vous vous basez sur une idée que quelqu'un d'autre a eue, veuillez l'attribuer. Vous pouvez essayer de perfectionner l'idée de quelqu'un d'autre, mais vous doit les attribuer.
Directives
Il s'agit essentiellement de règles qui peuvent être enfreintes, de suggestions ou de critères de notation :
- L'esthétique est importante. Je jugerai, et suggérerai que d'autres personnes jugent, en fonction de :
- La qualité de l'image de sortie, et sa ressemblance avec l'original.
- Comme le texte est beau. Un charabia complètement aléatoire est acceptable si vous disposez d'un système de compression vraiment intelligent, mais je veux aussi voir des réponses qui transforment des images en poèmes multilingues, ou quelque chose de ce genre. Notez que l'auteur de la solution originale a décidé d'utiliser uniquement des caractères chinois, car c'était plus joli ainsi.
- Un code intéressant et des algorithmes intelligents sont toujours bons. J'aime les codes courts, précis et clairs, mais les algorithmes complexes et intelligents ne posent pas de problème tant qu'ils donnent de bons résultats.
- La vitesse est également importante, mais pas autant que la qualité de la compression de l'image. Je préfère avoir un programme capable de convertir une image en un dixième de seconde plutôt qu'un programme qui fera tourner des algorithmes génétiques pendant des jours.
- Je préférerai les solutions courtes aux solutions plus longues, pour autant qu'elles soient de qualité raisonnablement comparable ; la concision est une vertu.
- Votre programme doit être implémenté dans un langage dont l'implémentation est librement disponible sur Mac OS X, Linux ou Windows. J'aimerais être en mesure d'exécuter les programmes, mais si vous avez une excellente solution qui ne fonctionne que sous Mac OS X, Linux ou Windows, vous pouvez l'utiliser. MATLAB ou autre, c'est bien.
- Votre programme doit être aussi général que possible ; il doit fonctionner pour autant d'images différentes que possible, bien que certaines puissent produire de meilleurs résultats que d'autres. En particulier :
- Le fait d'avoir quelques images intégrées dans le programme, qu'il fait correspondre et auxquelles il écrit une référence, puis qu'il produit l'image correspondante lors du décodage, est assez faible et ne couvrira que quelques images.
- Un programme capable de prendre des images de formes géométriques simples et plates et de les décomposer en une primitive vectorielle est plutôt intéressant, mais s'il échoue sur des images dépassant une certaine complexité, il n'est probablement pas assez général.
- Un programme qui ne peut prendre que des images d'un rapport d'aspect fixe particulier, mais qui fait du bon travail avec elles, serait également acceptable, mais pas idéal.
- Vous constaterez peut-être qu'une image en noir et blanc permet de faire entrer plus d'informations dans un espace plus restreint qu'une image en couleur. D'un autre côté, cela peut limiter les types d'images auxquels elle s'applique ; les visages ressortent bien en noir et blanc, mais les dessins abstraits ne s'en sortent pas aussi bien.
- Il n'y a pas de problème si l'image de sortie est plus petite que celle d'entrée, tout en ayant à peu près les mêmes proportions. Il n'y a pas de problème si vous devez mettre l'image à l'échelle pour la comparer à l'original ; ce qui est important, c'est son aspect.
- Votre programme doit produire des résultats qui pourraient passer par Twitter et en sortir indemnes. Il s'agit plus d'une directive que d'une règle, car je n'ai pas pu trouver de documentation sur l'ensemble précis des caractères pris en charge, mais vous devriez probablement éviter les caractères de contrôle, les caractères de combinaison invisibles funky, les caractères d'usage privé, etc.
Rubrique de notation
En guise de guide général sur la façon dont je vais classer les solutions lors du choix de la solution acceptée, disons que j'évaluerai probablement les solutions sur une échelle de 25 points (c'est très approximatif, et je ne vais pas noter quoi que ce soit directement, je l'utilise juste comme une ligne directrice de base) :
-
15 points pour la façon dont le système de codage reproduit un large éventail d'images d'entrée. Il s'agit d'un jugement subjectif et esthétique.
- 0 signifie qu'il ne fonctionne pas du tout, qu'il renvoie la même image à chaque fois, ou quelque chose comme ça.
- 5 signifie qu'il peut coder quelques images, bien que la version décodée soit moche et qu'il puisse ne pas fonctionner du tout sur des images plus complexes.
- 10 signifie qu'il fonctionne sur une large gamme d'images, et produit des images d'aspect agréable qui peuvent parfois être distinguées.
- 15 signifie qu'il produit des répliques parfaites de certaines images, et même pour des images plus grandes et plus complexes, il donne quelque chose qui est reconnaissable. Ou bien, peut-être qu'il ne produit pas d'images tout à fait reconnaissables, mais de belles images qui sont clairement dérivées de l'original.
-
3 points pour une utilisation intelligente du jeu de caractères Unicode
- 0 point pour l'utilisation de l'ensemble des caractères autorisés.
- 1 point pour l'utilisation d'un ensemble limité de caractères qui sont sûrs pour être transférés sur Twitter ou dans une plus grande variété de situations.
- 2 points pour l'utilisation d'un sous-ensemble thématique de caractères, par exemple uniquement les idéogrammes Han ou uniquement les caractères de droite à gauche.
- 3 points pour faire quelque chose de vraiment bien, comme générer un texte lisible ou utiliser des caractères qui ressemblent à l'image en question.
-
3 points pour des approches algorithmiques astucieuses et un style de code
- 0 point pour quelque chose qui représente 1000 lignes de code uniquement pour réduire l'échelle de l'image, la traiter comme un bit par pixel, et la coder en base64.
- 1 point pour quelque chose qui utilise une technique d'encodage standard et qui est bien écrit et bref.
- 2 points pour quelque chose qui introduit une technique de codage relativement nouvelle, ou qui est étonnamment court et propre.
- 3 points pour un one liner qui produit réellement de bons résultats, ou quelque chose qui innove dans l'encodage graphique (si cela semble un faible nombre de points pour innover, rappelez-vous qu'un résultat aussi bon aura probablement un score élevé pour l'esthétique également).
- 2 points pour la vitesse. Toutes choses égales par ailleurs, la rapidité est préférable, mais les critères ci-dessus sont tous plus importants que la vitesse.
- 1 point pour l'exécution sur un logiciel libre (open source), parce que je préfère les logiciels libres (notez que C# sera toujours éligible pour ce point tant qu'il fonctionne sur Mono, de même que le code MATLAB serait éligible s'il fonctionne sur GNU Octave)
- 1 point pour avoir respecté toutes les règles. Ces règles sont devenues un peu grandes et compliquées, donc je vais probablement accepter des réponses autrement bonnes qui ont un petit détail de travers, mais je donnerai un point supplémentaire à toute solution qui suit réellement toutes les règles.
Images de référence
Certaines personnes ont demandé des images de référence. Voici quelques images de référence que vous pouvez essayer ; des versions plus petites sont intégrées ici, elles renvoient toutes à des versions plus grandes de l'image si vous en avez besoin :
Prix
J'offre un Prime de 500 points (plus les 50 que StackOverflow ajoute) pour la solution qui me plaît le plus, sur la base des critères ci-dessus. Bien sûr, j'encourage tous les autres à voter pour leurs solutions préférées ici aussi.
Note sur le délai
Ce concours se déroulera jusqu'à ce que la prime soit épuisée, soit vers 18 heures le samedi 30 mai. Je ne peux pas dire l'heure précise à laquelle il se terminera ; cela peut être entre 17 et 19 heures. Je vous garantis que je regarderai toutes les contributions soumises avant 14 heures, et je ferai de mon mieux pour regarder toutes les contributions soumises avant 16 heures ; si les solutions sont soumises après cela, je n'aurai peut-être pas la chance de les regarder équitablement avant de devoir prendre ma décision. En outre, plus vous soumettez tôt votre solution, plus vous aurez de chances de voter pour m'aider à choisir la meilleure solution, alors essayez de soumettre votre solution plus tôt plutôt que juste à la date limite.
Notes sur l'Unicode
Il y a également eu une certaine confusion sur les caractères Unicode autorisés. L'éventail des points de code Unicode possibles est le suivant U+0000
à U+10FFFF
. Certains points de code ne sont jamais valables pour être utilisés comme caractères Unicode dans un échange ouvert de données ; il s'agit des points de code suivants non-caractères et le points de code de substitution . Les non-caractères sont définis dans le Norme Unidode 5.1.0 section 16.7 comme les valeurs U+FFFE
, U+FFFF
, U+
n FFFE
, U+
n FFFF
où n est 1
- 10
hexadécimal, et la plage U+FDD0
- U+FDEF
. Ces valeurs sont destinées à être utilisées pour un usage interne propre à l'application, et les applications conformes peuvent supprimer ces caractères du texte qu'elles traitent. Les points de code de substitution, définis dans le Norme Unicode 5.1.0 section 3.8 comme U+D800
- U+DFFF
sont utilisés pour encoder les caractères au-delà du plan multilingue de base dans l'UTF-16 ; il est donc impossible de représenter ces points de code directement dans l'encodage UTF-16, et il est invalide de les encoder dans tout autre encodage. Ainsi, pour les besoins de ce concours, j'autoriserai tout programme qui code des images en une séquence de 140 points de code Unicode au maximum parmi les suivants U+0000
- U+10FFFF
à l'exclusion de tous les non-caractères et des paires de substituts tels que définis ci-dessus.
Je vais préférez les solutions qui n'utilisent que des caractères assignés, et encore mieux celles qui utilisent des sous-ensembles intelligents de caractères assignés ou qui font quelque chose d'intéressant avec le jeu de caractères qu'elles utilisent. Pour obtenir une liste des caractères attribués, consultez la page Base de données des caractères Unicode ; notez que certains caractères sont listés directement, tandis que d'autres ne sont listés que comme début et fin d'une plage. Notez également que les points de code de substitution sont répertoriés dans la base de données, mais sont interdits comme mentionné ci-dessus. Si vous souhaitez tirer parti de certaines propriétés des caractères pour rendre le texte que vous produisez plus intéressant, il existe un certain nombre de possibilités. diverses bases de données d'informations sur les caractères disponible, tel qu'un liste des blocs de code nommés et diverses propriétés des personnages .
Étant donné que Twitter ne précise pas le jeu de caractères exact qu'il prend en charge, je serai indulgent à l'égard des solutions qui ne fonctionnent pas réellement avec Twitter parce que certains caractères comptent en plus ou que certains caractères sont supprimés. Il est préférable, mais pas obligatoire, que toutes les sorties codées puissent être transférées sans dommage via Twitter ou un autre service de microblogging tel que identi.ca . J'ai vu une documentation indiquant que Twitter codait en entités <, > et &, et les comptait donc comme 4, 4 et 5 caractères respectivement, mais je n'ai pas testé cela moi-même, et leur compteur de caractères JavaScript ne semble pas les compter de cette façon.
Conseils et liens
- La définition des caractères Unicode valides dans les règles est un peu compliquée. Il peut être plus facile de choisir un seul bloc de caractères, comme les idéogrammes unifiés du CJK (U+4E00-U+9FCF).
- Vous pouvez utiliser des bibliothèques d'images existantes, comme ImageMagick ou Bibliothèque d'imagerie Python pour la manipulation de vos images.
- Si vous avez besoin d'aide pour comprendre le jeu de caractères Unicode et ses différents codages, consultez le site suivant ce guide rapide ou cette FAQ détaillée sur UTF-8 dans Linux et Unix .
- Plus tôt vous enverrez votre solution, plus j'aurai le temps (et les autres votants) de l'examiner. Vous pouvez modifier votre solution si vous l'améliorez ; je baserai ma prime sur la version la plus récente lorsque je jetterai un dernier coup d'œil aux solutions.
- Si vous voulez un format d'image facile à analyser et à écrire (et que vous ne voulez pas simplement utiliser un format existant), je vous suggère d'utiliser la fonction Format PPM . Il s'agit d'un format texte très facile à utiliser, et vous pouvez vous servir des éléments suivants ImageMagick pour convertir vers et à partir de celui-ci.
Journal d'édition
30 mai : date limite de remise des prix, sélection du gagnant.
28 mai : détails plus précis sur la date limite
28 mai : Nettoyage des liens, mention de PPM
Le 27 mai : Réorganisation et nettoyage des règles et directives ; ajout de conseils et de liens.
Le 26 mai : Mention des problèmes de délais et suppression du plafond souple de 100 lignes.
22 mai : Ajout d'images de référence, de clarifications sur Unicode et d'une ébauche de grille de notation.
21 mai : mise à jour pour autoriser 140 caractères Unicode arbitraires. Alors que le formulaire web Twitter compte par unités de code UTF-16, l'API autorise 140 caractères Unicode arbitraires, nous allons donc utiliser cette définition pour permettre plus de flexibilité.
21 mai : Ajout d'informations sur la date limite
21 mai : publication du défi original