Si une image vaut 1 000 mots, quelle quantité d'image pouvez-vous contenir en 140 caractères?
Remarque : c'est tout! La date limite des primes est arrivée, et après quelques délibérations difficiles, j'ai décidé que l'entrée de Boojum venait à peine de devancer celle de Sam Hocevar . Je publierai des notes plus détaillées une fois que j'aurai eu l'occasion de les rédiger. Bien sûr, tout le monde devrait se sentir libre de continuer à soumettre des solutions et à améliorer les solutions pour que les gens votent. Merci à tous ceux qui ont soumis et participé; Je les ai tous appréciés. Cela a été très amusant pour moi de courir, et j'espère que ça a été amusant pour les participants et les spectateurs.
Je suis tombé sur cet article intéressant sur la compression des images dans un commentaire Twitter, et beaucoup de gens dans ce fil (et un fil sur Reddit ) avaient des suggestions sur différentes façons de le faire. Donc, je pense que ce serait un bon défi de codage; laissez les gens placer leur argent là où se trouve leur bouche et montrez comment leurs idées sur l'encodage peuvent donner plus de détails dans l'espace limité dont vous disposez.
Je vous mets au défi de trouver un système à usage général pour encoder les images en messages Twitter de 140 caractères et les décoder à nouveau en une image. Vous pouvez utiliser des caractères Unicode, vous obtenez donc plus de 8 bits par caractère. Même en autorisant les caractères Unicode, cependant, vous devrez compresser les images dans un très petit espace; ce sera certainement une compression avec perte, et il devra donc y avoir des jugements subjectifs sur la qualité de chaque résultat.
Voici le résultat que l'auteur original, Quasimondo , a obtenu de son encodage (l'image est sous licence Creative Commons Attribution-Noncommercial ):
Pouvez-vous faire mieux?
Règles
- Votre programme doit avoir deux modes: encodage et décodage .
- Lors de l' encodage :
- Votre programme doit prendre en entrée un graphique dans n'importe quel format graphique matriciel raisonnable de votre choix. Nous dirons que tout format raster pris en charge par ImageMagick compte comme raisonnable.
- Votre programme doit générer un message qui peut être représenté en 140 points de code Unicode ou moins; 140 points de code dans l'intervalle
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 gammeU+FDD0
-U+FDEF
) et des points de code de substitution (U+D800
-U+DFFF
). Il peut être sorti dans n'importe quel encodage raisonnable de votre choix; tout codage pris en charge par GNUiconv
sera considéré comme raisonnable, et le codage natif de votre plate-forme ou le codage local serait probablement un bon choix. Voir les notes Unicode ci-dessous pour plus de détails.
- Lors du décodage :
- Votre programme doit prendre en entrée la sortie de votre mode d' encodage .
- Votre programme doit sortir une image dans n'importe quel format raisonnable de votre choix, tel que défini ci-dessus, bien que les formats vectoriels de sortie soient également OK.
- La sortie d'image doit être une approximation de l'image d'entrée; plus vous vous rapprochez de l'image d'entrée, mieux c'est.
- Le processus de décodage peut n'avoir accès à aucune autre sortie du processus de codage autre que la sortie spécifiée ci-dessus; c'est-à-dire que vous ne pouvez pas télécharger l'image quelque part et sortir l'URL pour le processus de décodage à télécharger, ou quelque chose de stupide comme ça.
Par souci de cohérence dans l'interface utilisateur, votre programme doit se comporter comme suit:
- Votre programme doit être un script qui peut être défini sur exécutable sur une plate-forme avec 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
de régler le mode. Votre programme doit prendre des entrées d'une ou plusieurs des manières suivantes (si vous implémentez celui qui prend les noms de fichiers, vous pouvez également lire et écrire à partir de stdin et stdout si les noms de fichiers sont manquants):
Prenez l'entrée de l'entrée standard et produisez la sortie sur la sortie standard.
my-program encode <input.png >output.txt my-program decode <output.txt >output.png
Prenez l'entrée d'un fichier nommé dans le deuxième argument et produisez 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 quelque chose).
- Une explication de la façon dont cela fonctionne, si ce n'est pas immédiatement évident d'après le code ou si le code est long et les gens seront intéressés par un résumé.
- Une image d'exemple, avec l'image d'origine, le texte vers lequel elle est compressée et l'image décodée.
- Si vous construisez sur une idée que quelqu'un d'autre avait, veuillez les attribuer. C'est OK pour essayer d'affiner l'idée de quelqu'un d'autre, mais vous devez les attribuer.
Des lignes directrices
Ce sont essentiellement des règles qui peuvent être brisées, des suggestions ou des critères de notation:
- L'esthétique est importante. Je vais juger et suggérer que d'autres personnes jugent, sur la base de:
- La qualité de l'image de sortie et son aspect original.
- Comme c'est joli le texte. Un charabia complètement aléatoire est OK si vous avez un schéma de compression vraiment intelligent, mais je veux aussi voir des réponses qui transforment les images en poèmes multilingues, ou quelque chose d'intelligent comme ça. Notez que l'auteur de la solution originale a décidé de n'utiliser que des caractères chinois, car cela avait l'air plus agréable de cette façon.
- Un code intéressant et des algorithmes intelligents sont toujours bons. J'aime le code court, précis et clair, mais les algorithmes compliqués vraiment intelligents sont aussi OK tant qu'ils produisent de bons résultats.
- La vitesse est également importante, mais pas aussi importante que la qualité du travail de compression de l'image que vous faites. Je préfère avoir un programme qui peut convertir une image en un dixième de seconde plutôt que quelque chose qui exécutera des algorithmes génétiques pendant des jours.
- Je préférerai des solutions plus courtes à des solutions plus longues, pour autant qu'elles soient raisonnablement comparables en qualité; la concision est une vertu.
- Votre programme doit être implémenté dans une langue dont l'implémentation est disponible gratuitement sur Mac OS X, Linux ou Windows. J'aimerais pouvoir exécuter les programmes, mais si vous avez une excellente solution qui ne fonctionne que sous MATLAB ou quelque chose, ça va.
- Votre programme doit être aussi général que possible; cela devrait fonctionner pour autant d'images différentes que possible, bien que certaines puissent produire de meilleurs résultats que d'autres. En particulier:
- Avoir quelques images intégrées dans le programme auquel il correspond et écrit une référence, puis produit l'image correspondante lors du décodage, est assez boiteux et ne couvrira que quelques images.
- Un programme qui peut prendre des images de formes géométriques simples et plates et les décomposer en une primitive vectorielle est assez astucieux, mais s'il échoue sur des images au-delà d'une certaine complexité, il est probablement insuffisamment 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 OK, mais pas idéal.
- Vous pouvez constater qu'une image en noir et blanc peut obtenir plus d'informations dans un espace plus petit 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 motifs abstraits peuvent ne pas être aussi bons.
- C'est parfaitement bien si l'image de sortie est plus petite que l'entrée, tout en étant à peu près la même proportion. C'est OK si vous devez redimensionner l'image pour la comparer à l'original; ce qui est important, c'est à quoi ça ressemble.
- Votre programme devrait produire une sortie qui pourrait réellement passer par Twitter et sortir indemne. Ce n'est qu'une directive plutôt qu'une règle, car je n'ai trouvé aucune documentation sur l'ensemble précis de caractères pris en charge, mais vous devriez probablement éviter les caractères de contrôle, les caractères de combinaison invisibles géniaux, les caractères à usage privé, etc.
Rubrique de notation
En tant que guide général sur la façon dont je classerai les solutions lors du choix de ma solution acceptée, disons que je vais probablement évaluer les solutions sur une échelle de 25 points (c'est très approximatif, et je ne noterai rien directement, en utilisant simplement ceci comme ligne directrice de base):
- 15 points pour la façon dont le schéma de codage reproduit une large gamme d'images d'entrée. Il s'agit d'un jugement subjectif et esthétique
- 0 signifie que cela ne fonctionne pas du tout, il renvoie la même image à chaque fois, ou quelque chose
- 5 signifie qu'il peut encoder quelques images, bien que la version décodée semble moche et qu'elle ne fonctionne pas du tout sur des images plus compliquées
- 10 signifie qu'il fonctionne sur une large gamme d'images et produit des images agréables 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, donne quelque chose qui est reconnaissable. Ou, peut-être que cela ne rend pas les images tout à fait reconnaissables, mais produit 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 utiliser simplement l'ensemble des caractères autorisés
- 1 point pour l'utilisation d'un ensemble limité de caractères pouvant être transférés en toute sécurité 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, comme 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 du texte lisible ou utiliser des caractères qui ressemblent à l'image en question
- 3 points pour des approches algorithmiques intelligentes et un style de code
- 0 point pour quelque chose qui représente 1 000 lignes de code uniquement pour réduire l'image, la traiter comme 1 bit par pixel et encoder en base64 qui
- 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 d'encodage relativement nouvelle, ou qui est étonnamment court et propre
- 3 points pour une doublure qui produit réellement de bons résultats, ou quelque chose qui innove dans l'encodage graphique (si cela semble être un faible nombre de points pour innover, rappelez-vous qu'un résultat de ce produit aura probablement un score élevé pour l'esthétique ainsi que)
- 2 points pour la vitesse. Toutes choses étant égales par ailleurs, plus vite c'est mieux, mais les critères ci-dessus sont tous plus importants que la vitesse
- 1 point pour fonctionner sur un logiciel libre (open source), car je préfère le logiciel libre (notez que C # sera toujours éligible pour ce point tant qu'il fonctionnera en Mono, de même le code MATLAB serait éligible s'il s'exécute sur GNU Octave)
- 1 point pour avoir suivi toutes les règles. Ces règles sont devenues un peu grosses et compliquées, donc j'accepterai probablement de bonnes réponses qui se trompent un petit détail, 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 sont toutes liées à des versions plus grandes de l'image si vous en avez besoin:
Prix
J'offre une prime de 500 représentants (plus les 50 que StackOverflow entre en jeu) pour la solution que j'aime le mieux, en fonction des critères ci-dessus. Bien sûr, j'encourage tout le monde à voter sur leurs solutions préférées ici également.
Remarque sur la date limite
Ce concours se poursuivra jusqu'à épuisement de la prime, vers 18 h le samedi 30 mai. Je ne peux pas dire l'heure exacte à laquelle il se terminera; il peut être de 17 h à 19 h. Je garantirai que je regarderai toutes les entrées soumises avant 14 heures, et je ferai de mon mieux pour regarder toutes les entrées soumises avant 16 heures; si des solutions sont soumises après cela, je n'aurai peut-être pas la possibilité de leur donner un aperçu juste avant de devoir prendre ma décision. De plus, plus vous soumettez tôt, plus vous aurez de chances de voter pour être en mesure de m'aider à choisir la meilleure solution, alors essayez de soumettre plus tôt plutôt que juste à la date limite.
Notes Unicode
Il y a également eu une certaine confusion sur exactement quels caractères Unicode sont autorisés. La plage de points de code Unicode possibles est U+0000
de U+10FFFF
. Il existe certains points de code qui ne sont jamais valables pour être utilisés comme caractères Unicode dans tout échange ouvert de données; ce sont les non- caractères et les points de code de substitution . Non - caractères sont définis dans la norme section 5.1.0 Unidode 16,7 comme les valeurs U+FFFE
, U+FFFF
, U+
nFFFE
, U+
nFFFF
où n est 1
- 10
hexadécimal, et la gamme U+FDD0
-U+FDEF
. Ces valeurs sont destinées à être utilisées pour une utilisation interne spécifique à l'application, et les applications conformes peuvent supprimer ces caractères du texte qu'ils traitent. Les points de code de substitution, définis dans la norme Unicode 5.1.0 section 3.8 as U+D800
- U+DFFF
, sont utilisés pour coder les caractères au-delà du plan multilingue de base en UTF-16; ainsi, il est impossible de représenter ces points de code directement dans le codage UTF-16, et il n'est pas valide de les coder dans un autre codage. Ainsi, aux fins de ce concours, j'autoriserai tout programme qui code des images dans une séquence de 140 points de code Unicode au maximum de la plage U+0000
- U+10FFFF
, à l'exclusion de tous les non-caractères et paires de substitution tels que définis ci-dessus.
Je préférerai des solutions qui n'utilisent que des caractères attribués, et encore mieux celles qui utilisent des sous-ensembles intelligents de caractères attribués ou font quelque chose d'intéressant avec le jeu de caractères qu'ils utilisent. Pour une liste des caractères attribués, consultez la base de données de caractères Unicode ; notez que certains caractères sont répertoriés directement, tandis que certains ne sont répertoriés que comme le début et la fin d'une plage. Notez également que les points de code de substitution sont répertoriés dans la base de données, mais interdits comme mentionné ci-dessus. Si vous souhaitez profiter de certaines propriétés des caractères pour rendre le texte que vous sortez plus intéressant, il existe une variété de bases de données d'informations sur les caractères , telles qu'une liste de blocs de code nommés et diverses propriétés de caractères.
Étant donné que Twitter ne spécifie pas le jeu de caractères exact qu'ils prennent en charge, je me montrerai indulgent vis-à-vis des solutions qui ne fonctionnent pas réellement avec Twitter car certains caractères comptent en plus ou certains caractères sont supprimés. Il est préférable, mais non obligatoire, que toutes les sorties codées puissent être transférées indemnes via Twitter ou un autre service de microblogage tel que identi.ca . J'ai vu de la documentation indiquant que Twitter code les entités <,> et &, et les compte donc comme 4, 4 et 5 caractères respectivement, mais je ne l'ai pas testé moi-même, et leur compteur de caractères JavaScript ne semble pas de 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. Le choix d'un seul bloc de caractères, comme les idéogrammes unifiés CJC (U + 4E00 – U + 9FCF) peut être plus facile.
- Vous pouvez utiliser des bibliothèques d'images existantes, comme ImageMagick ou Python Imaging Library , pour votre manipulation d'image.
- Si vous avez besoin d'aide pour comprendre le jeu de caractères Unicode et ses différents encodages, consultez ce guide rapide ou cette FAQ détaillée sur UTF-8 sous Linux et Unix .
- Plus tôt vous obtiendrez votre solution, plus je (et les autres personnes votant) devrai y réfléchir. Vous pouvez modifier votre solution si vous l'améliorez; Je baserai ma prime sur la version la plus récente lors de mon dernier examen des solutions.
- Si vous voulez un format d'image facile à analyser et à écrire (et ne voulez pas simplement utiliser un format existant), je vous suggère d'utiliser le format PPM . Il s'agit d'un format basé sur du texte qui est très facile à utiliser, et vous pouvez utiliser ImageMagick pour convertir vers et depuis celui-ci.