Si una imagen vale más que 1000 palabras, ¿cuánto de una imagen puede caber en 140 caracteres?
Nota : ¡Eso es todo amigos! La fecha límite de la recompensa está aquí, y después de algunas duras deliberaciones, he decidido que la entrada de Boojum apenas superó a la de Sam Hocevar . Publicaré notas más detalladas una vez que haya tenido la oportunidad de escribirlas. Por supuesto, todos deberían sentirse libres de continuar presentando soluciones y mejorar las soluciones para que las personas voten. Gracias a todos los que presentaron y la entrada; Los disfruté todos. Ha sido muy divertido para mí correr, y espero que haya sido divertido tanto para los participantes como para los espectadores.
Me encontré con esta publicación interesante sobre tratar de comprimir imágenes en un comentario de Twitter, y muchas personas en ese hilo (y un hilo en Reddit ) tenían sugerencias sobre las diferentes formas en que puedes hacerlo. Entonces, supongo que sería un buen desafío de codificación; deje que las personas pongan su dinero donde está su boca y muestre cómo sus ideas sobre la codificación pueden conducir a más detalles en el espacio limitado que tiene disponible.
Te reto a que encuentres un sistema de propósito general para codificar imágenes en mensajes de Twitter de 140 caracteres y decodificarlas nuevamente en una imagen. Puede usar caracteres Unicode, por lo que obtiene más de 8 bits por carácter. Sin embargo, incluso teniendo en cuenta los caracteres Unicode, deberá comprimir las imágenes en una cantidad muy pequeña de espacio; esto sin duda será una compresión con pérdida, por lo que tendrá que haber juicios subjetivos sobre qué tan bien se ve cada resultado.
Aquí está el resultado que el autor original, Quasimondo , obtuvo de su codificación (la imagen está licenciada bajo una licencia Creative Commons Reconocimiento-No comercial ):
¿Puedes hacerlo mejor?
Reglas
- Su programa debe tener dos modos: codificación y decodificación .
- Al codificar :
- Su programa debe tomar como entrada un gráfico en cualquier formato gráfico de trama razonable que elija. Diremos que cualquier formato de trama admitido por ImageMagick cuenta como razonable.
- Su programa debe generar un mensaje que se pueda representar en 140 o menos puntos de código Unicode; 140 puntos de código en el rango de
U+0000
-U+10FFFF
, con exclusión de los no caracteres (U+FFFE
,U+FFFF
,U+
nFFFE
,U+
nFFFF
, donde n es1
-10
hexadecimal, y la gamaU+FDD0
-U+FDEF
) y puntos de código de sustitución (U+D800
-U+DFFF
). Puede salir en cualquier codificación razonable de su elección; cualquier codificación admitida por GNUiconv
se considerará razonable, y la codificación nativa de su plataforma o codificación local probablemente sea una buena opción. Consulte las notas de Unicode a continuación para obtener más detalles.
- Al decodificar :
- Su programa debe tomar como entrada la salida de su modo de codificación .
- Su programa debe generar una imagen en cualquier formato razonable de su elección, como se definió anteriormente, aunque para los formatos de vector de salida también están bien.
- La salida de la imagen debe ser una aproximación de la imagen de entrada; cuanto más se acerque a la imagen de entrada, mejor.
- El proceso de decodificación puede no tener acceso a ninguna otra salida del proceso de codificación que no sea la salida especificada anteriormente; es decir, no puede cargar la imagen en algún lugar y generar la URL para que se descargue el proceso de decodificación, o algo así de tonto.
En aras de la coherencia en la interfaz de usuario, su programa debe comportarse de la siguiente manera:
- Su programa debe ser un script que pueda configurarse como ejecutable en una plataforma con el intérprete apropiado, o un programa que pueda compilarse en un ejecutable.
- Su programa debe tomar como primer argumento
encode
odecode
para establecer el modo. Su programa debe recibir información de una o más de las siguientes maneras (si implementa el que toma nombres de archivos, también puede leer y escribir desde stdin y stdout si faltan nombres de archivo):
Tome la entrada de entrada estándar y produzca salida en salida estándar.
my-program encode <input.png >output.txt my-program decode <output.txt >output.png
Tome datos de un archivo nombrado en el segundo argumento y produzca resultados en el archivo nombrado en el tercero.
my-program encode input.png output.txt my-program decode output.txt output.png
- Para su solución, publique:
- Su código, en su totalidad, y / o un enlace a él alojado en otro lugar (si es muy largo, o requiere muchos archivos para compilar, o algo así).
- Una explicación de cómo funciona, si no es inmediatamente obvio por el código o si el código es largo y las personas estarán interesadas en un resumen.
- Una imagen de ejemplo, con la imagen original, el texto que comprime y la imagen decodificada.
- Si está construyendo sobre una idea que alguien más tuvo, por favor atribuyala. Está bien intentar refinar la idea de otra persona, pero debe atribuirla.
Pautas
Estas son básicamente reglas que pueden romperse, sugerencias o criterios de puntuación:
- La estética es importante. Estaré juzgando, y sugeriré que otras personas juzguen, en base a:
- Qué bien se ve la imagen de salida y cuánto se parece al original.
- Qué bonito se ve el texto. Gobbledigook completamente al azar está bien si tienes un esquema de compresión realmente inteligente, pero también quiero ver respuestas que conviertan las imágenes en poemas multilingües, o algo así. Tenga en cuenta que el autor de la solución original decidió usar solo caracteres chinos, ya que se veía mejor de esa manera.
- El código interesante y los algoritmos inteligentes siempre son buenos. Me gusta el código corto y directo, pero los algoritmos realmente inteligentes y complicados también están bien siempre que produzcan buenos resultados.
- La velocidad también es importante, aunque no tan importante como lo bueno que es comprimir la imagen que haces. Prefiero tener un programa que pueda convertir una imagen en una décima de segundo que algo que ejecute algoritmos genéticos durante días.
- Preferiré soluciones más cortas a las más largas, siempre que sean razonablemente comparables en calidad; la concisión es una virtud.
- Su programa debe implementarse en un lenguaje que tenga una implementación disponible gratuitamente en Mac OS X, Linux o Windows. Me gustaría poder ejecutar los programas, pero si tienes una gran solución que solo se ejecuta bajo MATLAB o algo así, está bien.
- Su programa debe ser lo más general posible; debería funcionar para tantas imágenes diferentes como sea posible, aunque algunas pueden producir mejores resultados que otras. En particular:
- Tener algunas imágenes integradas en el programa con las que coincide y escribe una referencia, y luego produce la imagen coincidente después de la decodificación, es bastante aburrido y solo cubrirá unas pocas imágenes.
- Un programa que puede tomar imágenes de formas simples, planas y geométricas y descomponerlas en un vector primitivo es bastante ingenioso, pero si falla en imágenes más allá de una cierta complejidad, probablemente sea insuficientemente general.
- Un programa que solo pueda tomar imágenes de una relación de aspecto fija particular pero que haga un buen trabajo con ellas también estaría bien, pero no es ideal.
- Puede encontrar que una imagen en blanco y negro puede obtener más información en un espacio más pequeño que una imagen en color. Por otro lado, eso puede limitar los tipos de imagen a los que es aplicable; las caras salen bien en blanco y negro, pero los diseños abstractos pueden no funcionar tan bien
- Está perfectamente bien si la imagen de salida es más pequeña que la entrada, mientras que es aproximadamente la misma proporción. Está bien si tiene que escalar la imagen para compararla con el original; Lo importante es cómo se ve.
- Su programa debe producir resultados que realmente puedan pasar por Twitter y salir ilesos. Esto es solo una guía en lugar de una regla, ya que no pude encontrar ninguna documentación sobre el conjunto preciso de caracteres admitidos, pero probablemente debería evitar los caracteres de control, los caracteres combinados invisibles funky, los caracteres de uso privado y similares.
Rúbrica de puntuación
Como una guía general sobre cómo clasificaré las soluciones al elegir mi solución aceptada, digamos que probablemente evaluaré las soluciones en una escala de 25 puntos (esto es muy aproximado, y no voy a puntuar nada directamente, solo usando esto como una guía básica):
- 15 puntos sobre qué tan bien el esquema de codificación reproduce una amplia gama de imágenes de entrada. Este es un juicio subjetivo y estético.
- 0 significa que no funciona en absoluto, devuelve la misma imagen cada vez, o algo
- 5 significa que puede codificar algunas imágenes, aunque la versión decodificada se ve fea y es posible que no funcione en imágenes más complicadas
- 10 significa que funciona en una amplia gama de imágenes y produce imágenes de aspecto agradable que en ocasiones pueden distinguirse
- 15 significa que produce réplicas perfectas de algunas imágenes, e incluso para imágenes más grandes y complejas, proporciona algo que es reconocible. O, tal vez, no crea imágenes que sean bastante reconocibles, sino que produce bellas imágenes que se derivan claramente del original.
- 3 puntos por el uso inteligente del juego de caracteres Unicode
- 0 puntos por simplemente usar todo el conjunto de caracteres permitidos
- 1 punto por usar un conjunto limitado de caracteres que son seguros para transferir a través de Twitter o en una variedad más amplia de situaciones
- 2 puntos por usar un subconjunto temático de caracteres, como solo ideógrafos Han o solo caracteres de derecha a izquierda
- 3 puntos por hacer algo realmente bueno, como generar texto legible o usar caracteres que se parezcan a la imagen en cuestión
- 3 puntos para enfoques algorítmicos inteligentes y estilo de código
- 0 puntos para algo que son 1000 líneas de código solo para reducir la imagen, tratarla como 1 bit por píxel y codificar en base64
- 1 punto para algo que usa una técnica de codificación estándar y está bien escrito y es breve
- 2 puntos para algo que introduce una técnica de codificación relativamente novedosa, o que es sorprendentemente corta y limpia
- 3 puntos para un trazador de líneas que realmente produce buenos resultados, o algo que abre nuevos caminos en la codificación de gráficos (si esto parece un número bajo de puntos por abrir nuevos caminos, recuerde que un resultado tan bueno probablemente tendrá una puntuación alta en estética) también)
- 2 puntos por velocidad. Todo lo demás es igual, más rápido es mejor, pero los criterios anteriores son más importantes que la velocidad
- 1 punto por ejecutarse en software libre (de código abierto), porque prefiero el software libre (tenga en cuenta que C # seguirá siendo elegible para este punto siempre que se ejecute en Mono, del mismo modo el código MATLAB sería elegible si se ejecuta en GNU Octave)
- 1 punto por seguir realmente todas las reglas. Estas reglas se han vuelto un poco grandes y complicadas, por lo que probablemente acepte respuestas buenas que de otra manera obtendrían un pequeño detalle incorrecto, pero daré un punto adicional a cualquier solución que realmente siga todas las reglas
Imágenes de referencia
Algunas personas han pedido algunas imágenes de referencia. Aquí hay algunas imágenes de referencia que puede probar; Aquí se incrustan versiones más pequeñas, todas se vinculan a versiones más grandes de la imagen si las necesita:
Premio
Estoy ofreciendo una recompensa de 500 repeticiones (más las 50 que inicia StackOverflow) para la solución que más me gusta, según los criterios anteriores. Por supuesto, también animo a todos los demás a votar sobre sus soluciones favoritas aquí.
Nota sobre plazo
Este concurso se extenderá hasta que se acabe la recompensa, alrededor de las 6 PM del sábado 30 de mayo. No puedo decir la hora exacta en que terminará; Puede ser de 5 a 7 PM. Garantizaré que miraré todas las entradas enviadas antes de las 2 PM, y haré todo lo posible para mirar todas las entradas enviadas antes de las 4 PM; Si se presentan soluciones después de eso, es posible que no tenga la oportunidad de darles un vistazo justo antes de tener que tomar una decisión. Además, cuanto antes envíe, más posibilidades tendrá de votar para ayudarme a elegir la mejor solución, así que intente enviarlo antes que en la fecha límite.
Notas Unicode
También ha habido cierta confusión sobre exactamente qué caracteres Unicode están permitidos. El rango de posibles puntos de código Unicode es U+0000
a U+10FFFF
. Hay algunos puntos de código que nunca son válidos para usar como caracteres Unicode en cualquier intercambio abierto de datos; Estos son los no caracteres y los puntos de código sustituto . Noncharacters se definen en el 5.1.0 sección Unidode Standard 16.7 como los valores U+FFFE
, U+FFFF
, U+
nFFFE
, U+
nFFFF
, donde n es 1
- 10
hexadecimal, y la gama U+FDD0
-U+FDEF
. Estos valores están destinados a ser utilizados para uso interno específico de la aplicación, y las aplicaciones conformes pueden quitar estos caracteres del texto procesado por ellos. Los puntos de código sustituto, definidos en la sección 3.8 de Unicode Standard 5.1.0 como U+D800
- U+DFFF
, se utilizan para codificar caracteres más allá del plano multilingüe básico en UTF-16; por lo tanto, es imposible representar estos puntos de código directamente en la codificación UTF-16, y no es válido codificarlos en ninguna otra codificación. Así, para el propósito de este concurso, voy a permitir que cualquier programa que codifica imágenes en una secuencia de no más de 140 puntos de código Unicode de la gama U+0000
- U+10FFFF
, excluyendo todos los noncharacters y pares suplentes como se definió anteriormente.
Voy a preferir soluciones que utilizan únicamente caracteres asignados, y los aún mejores que utilizan subconjuntos inteligente de caracteres asignados o hacer algo interesante con el juego de caracteres que utilizan. Para obtener una lista de los caracteres asignados, consulte la base de datos de caracteres Unicode ; tenga en cuenta que algunos caracteres se enumeran directamente, mientras que otros se enumeran solo como el inicio y el final de un rango. También tenga en cuenta que los puntos de código sustituto se enumeran en la base de datos, pero están prohibidos como se mencionó anteriormente. Si desea aprovechar ciertas propiedades de los caracteres para hacer que el texto que imprime sea más interesante, hay una variedad de bases de datos de información de caracteres disponibles, como una lista de bloques de código con nombre y varias propiedades de caracteres..
Como Twitter no especifica el conjunto exacto de caracteres que admiten, seré indulgente con las soluciones que en realidad no funcionan con Twitter porque ciertos caracteres cuentan más o se eliminan ciertos caracteres. Se prefiere, pero no es obligatorio, que todas las salidas codificadas se puedan transferir sin daños a través de Twitter u otro servicio de microblogging como identi.ca . He visto cierta documentación que indica que la entidad de Twitter codifica <,> y &, y por lo tanto los cuenta como 4, 4 y 5 caracteres respectivamente, pero no lo he probado yo mismo, y su contador de caracteres de JavaScript no parece contarlos de esa manera.
Consejos y enlaces
- La definición de caracteres Unicode válidos en las reglas es un poco complicada. Elegir un solo bloque de caracteres, como los ideógrafos unificados CJK (U + 4E00 – U + 9FCF) puede ser más fácil.
- Puede utilizar bibliotecas de imágenes existentes, como ImageMagick o Python Imaging Library , para la manipulación de su imagen.
- Si necesita ayuda para comprender el juego de caracteres Unicode y sus diversas codificaciones, consulte esta guía rápida o estas Preguntas frecuentes detalladas sobre UTF-8 en Linux y Unix .
- Cuanto antes obtenga su solución, más tiempo tendré que verla (y otras personas que voten). Puede editar su solución si la mejora; Basaré mi recompensa en la versión más reciente cuando eche un vistazo a las soluciones.
- Si desea un formato de imagen fácil de analizar y escribir (y no desea simplemente usar un formato existente), le sugiero que use el formato PPM . Es un formato basado en texto con el que es muy fácil trabajar, y puede usar ImageMagick para convertir ay desde él.