Se uma imagem vale mais que 1000 palavras, quanto da imagem você pode caber em 140 caracteres?
Nota : É isso aí pessoal! Chegou o prazo da recompensa e, após algumas deliberações difíceis, decidi que a entrada de Boojum mal superava a de Sam Hocevar . Vou postar notas mais detalhadas assim que tiver a chance de escrevê-las. Obviamente, todos devem se sentir à vontade para continuar enviando soluções e aprimorando soluções para as pessoas votarem. Obrigado a todos que enviaram e inscrevem-se; Eu gostei de todos eles. Isso foi muito divertido para mim, e espero que tenha sido divertido tanto para os participantes quanto para os espectadores.
Me deparei com este post interessante sobre como tentar compactar imagens em um comentário no Twitter, e muitas pessoas nesse tópico (e um tópico no Reddit ) tinham sugestões sobre diferentes maneiras de fazer isso. Então, acho que seria um bom desafio de codificação; permita que as pessoas coloquem seu dinheiro onde estão, e mostre como suas idéias sobre codificação podem levar a mais detalhes no espaço limitado disponível.
Desafio você a criar um sistema de uso geral para codificar imagens em mensagens do Twitter com 140 caracteres e decodificá-las em uma imagem novamente. Você pode usar caracteres Unicode para obter mais de 8 bits por caractere. Mesmo permitindo caracteres Unicode, no entanto, você precisará compactar imagens em uma quantidade muito pequena de espaço; isso certamente será uma compactação com perdas e, portanto, terá que haver julgamentos subjetivos sobre a qualidade de cada resultado.
Aqui está o resultado que o autor original, Quasimondo , obteve de sua codificação (a imagem é licenciada sob uma licença Creative Commons Attribution-Noncommercial ):
Você pode fazer melhor?
Regras
- Seu programa deve ter dois modos: codificação e decodificação .
- Ao codificar :
- Seu programa deve ter como entrada um gráfico em qualquer formato gráfico de varredura razoável de sua escolha. Diremos que qualquer formato raster suportado pelo ImageMagick conta como razoável.
- Seu programa deve gerar uma mensagem que possa ser representada em 140 ou menos pontos de código Unicode; 140 pontos de código no intervalo
U+0000
-U+10FFFF
, excluindo não caracteres (U+FFFE
,U+FFFF
,U+
nFFFE
,U+
nFFFF
, onde n é1
-10
hexadecimal, e a gamaU+FDD0
-U+FDEF
) e pontos de código substituto (U+D800
-U+DFFF
). Pode ser produzido em qualquer codificação razoável de sua escolha; qualquer codificação suportada pelo GNUiconv
será considerada razoável, e a codificação nativa ou local de sua plataforma provavelmente será uma boa opção. Veja as notas Unicode abaixo para mais detalhes.
- Ao decodificar :
- Seu programa deve ter como entrada a saída do seu modo de codificação .
- Seu programa deve gerar uma imagem em qualquer formato razoável de sua escolha, conforme definido acima, embora os formatos vetoriais de saída também sejam aceitáveis.
- A saída da imagem deve ser uma aproximação da imagem de entrada; quanto mais perto você estiver da imagem de entrada, melhor.
- O processo de decodificação pode não ter acesso a nenhuma outra saída do processo de codificação além da saída especificada acima; ou seja, você não pode fazer upload da imagem em algum lugar e gerar o URL para o processo de decodificação baixar, ou algo parecido.
Por uma questão de consistência na interface do usuário, seu programa deve se comportar da seguinte maneira:
- Seu programa deve ser um script que possa ser definido como executável em uma plataforma com o intérprete apropriado ou um programa que possa ser compilado em um executável.
- Seu programa deve tomar como seu primeiro argumento
encode
oudecode
para definir o modo. Seu programa deve receber entradas de uma ou mais das seguintes maneiras (se você implementar a que aceita nomes de arquivos, também poderá ler e gravar a partir de stdin e stdout se houver nomes ausentes):
Capte a entrada da entrada padrão e produza saída com saída padrão.
my-program encode <input.png >output.txt my-program decode <output.txt >output.png
Pegue a entrada de um arquivo nomeado no segundo argumento e produza saída no arquivo nomeado no terceiro.
my-program encode input.png output.txt my-program decode output.txt output.png
- Para sua solução, poste:
- Seu código, na íntegra, e / ou um link para ele hospedado em outro local (se for muito longo ou exigir muitos arquivos para compilar, ou algo assim).
- Uma explicação de como funciona, se não for imediatamente óbvio no código ou se o código for longo e as pessoas se interessarem em um resumo.
- Uma imagem de exemplo, com a imagem original, o texto compactado e a imagem decodificada.
- Se você está construindo uma ideia que alguém teve, atribua-a. Não há problema em tentar refinar a ideia de outra pessoa, mas você deve atribuí-la.
Diretrizes
Estas são basicamente regras que podem ser quebradas, sugestões ou critérios de pontuação:
- A estética é importante. Vou julgar e sugerir que outras pessoas julguem, com base em:
- Qual a aparência da imagem de saída e a aparência da original.
- Que bom o texto parece. O gobbledigook completamente aleatório é bom se você tiver um esquema de compactação realmente inteligente, mas também quero ver respostas que transformam imagens em poemas multilíngües ou algo assim. Observe que o autor da solução original decidiu usar apenas caracteres chineses, pois parecia melhor assim.
- Código interessante e algoritmos inteligentes são sempre bons. Gosto de códigos curtos, diretos e claros, mas algoritmos complicados muito inteligentes são bons demais desde que produzam bons resultados.
- A velocidade também é importante, embora não seja tão importante quanto a qualidade de um trabalho para compactar a imagem que você faz. Prefiro ter um programa que possa converter uma imagem em um décimo de segundo do que algo que estará executando algoritmos genéticos por dias a fio.
- Prefiro soluções mais curtas a soluções mais longas, desde que sejam razoavelmente comparáveis em qualidade; concisão é uma virtude.
- Seu programa deve ser implementado em um idioma que tenha uma implementação disponível gratuitamente no Mac OS X, Linux ou Windows. Eu gostaria de poder executar os programas, mas se você tem uma ótima solução que roda apenas no MATLAB ou algo assim, tudo bem.
- Seu programa deve ser o mais geral possível; deve funcionar com tantas imagens diferentes quanto possível, embora algumas possam produzir melhores resultados do que outras. Em particular:
- Ter algumas imagens integradas no programa às quais corresponde e gravar uma referência e depois produz a imagem correspondente após a decodificação é bastante ruim e cobrirá apenas algumas imagens.
- Um programa que pode capturar imagens de formas simples, planas e geométricas e decompô-las em algum vetor primitivo é bastante bacana, mas se falhar nas imagens além de uma certa complexidade, provavelmente será insuficientemente geral.
- Um programa que só pode capturar imagens de uma determinada proporção fixa, mas faz um bom trabalho com elas também seria bom, mas não ideal.
- Você pode achar que uma imagem em preto e branco pode obter mais informações em um espaço menor que uma imagem colorida. Por outro lado, isso pode limitar os tipos de imagem aos quais é aplicável; os rostos saem bem em preto e branco, mas os desenhos abstratos podem não se sair tão bem.
- É perfeitamente adequado se a imagem de saída for menor que a entrada, enquanto estiver aproximadamente na mesma proporção. Tudo bem se você precisar ampliar a imagem para compará-la ao original; o importante é como fica.
- Seu programa deve produzir resultados que possam realmente passar pelo Twitter e sair ilesos. Isso é apenas uma diretriz e não uma regra, já que não consegui encontrar nenhuma documentação sobre o conjunto preciso de caracteres suportados, mas você provavelmente deve evitar caracteres de controle, caracteres combinados invisíveis e funky, caracteres de uso privado e similares.
Rubrica de pontuação
Como um guia geral de como classificarei as soluções ao escolher minha solução aceita, digamos que provavelmente avaliarei soluções em uma escala de 25 pontos (isso é muito difícil e não pontuarei nada diretamente, apenas usando como orientação básica):
- 15 pontos sobre o quão bem o esquema de codificação reproduz uma ampla gama de imagens de entrada. Este é um julgamento subjetivo, estético
- 0 significa que não funciona, devolve a mesma imagem sempre, ou algo assim
- 5 significa que ele pode codificar algumas imagens, embora a versão decodificada pareça feia e possa não funcionar em imagens mais complicadas
- 10 significa que ele funciona em uma ampla variedade de imagens e produz imagens de aparência agradável que podem ocasionalmente ser distinguíveis
- 15 significa que produz réplicas perfeitas de algumas imagens e, mesmo para imagens maiores e mais complexas, fornece algo que é reconhecível. Ou talvez não faça imagens que sejam bastante reconhecíveis, mas produz imagens bonitas que são claramente derivadas do original.
- 3 pontos para o uso inteligente do conjunto de caracteres Unicode
- 0 pontos por simplesmente usar todo o conjunto de caracteres permitidos
- 1 ponto para usar um conjunto limitado de caracteres que são seguros para transferência pelo Twitter ou em uma variedade maior de situações
- 2 pontos para usar um subconjunto temático de caracteres, como apenas ideogramas Han ou apenas caracteres da direita para a esquerda
- 3 pontos para fazer algo realmente interessante, como gerar texto legível ou usar caracteres que se parecem com a imagem em questão
- 3 pontos para abordagens algorítmicas inteligentes e estilo de código
- 0 pontos para algo que é de 1000 linhas de código apenas para reduzir a imagem, tratá-la como 1 bit por pixel e codificar base64 que
- 1 ponto para algo que usa uma técnica de codificação padrão e é bem escrito e breve
- 2 pontos para algo que introduz uma técnica de codificação relativamente nova ou que é surpreendentemente curta e limpa
- 3 pontos para um liner que realmente produz bons resultados, ou algo que abre novos caminhos na codificação gráfica (se isso parecer um número baixo de pontos para abrir novos caminhos, lembre-se de que um resultado desse bom provavelmente terá uma pontuação alta em estética também)
- 2 pontos por velocidade. Tudo o resto é igual, mais rápido é melhor, mas os critérios acima são todos mais importantes que a velocidade
- 1 ponto para execução no software livre (código aberto), porque eu prefiro o software livre (observe que o C # ainda será elegível para esse ponto enquanto for executado no Mono, da mesma forma o código MATLAB seria elegível se for executado no GNU Octave)
- 1 ponto para realmente seguir todas as regras. Essas regras ficaram um pouco grandes e complicadas, então provavelmente aceitarei boas respostas que apresentem um pequeno detalhe errado, mas darei um ponto extra a qualquer solução que realmente siga todas as regras
Imagens de referência
Algumas pessoas pediram algumas imagens de referência. Aqui estão algumas imagens de referência que você pode tentar; versões menores são incorporadas aqui, todas elas se vinculam a versões maiores da imagem, se você precisar delas:
Prêmio
Estou oferecendo uma recompensa de 500 representantes (mais os 50 que o StackOverflow oferece ) para a solução que eu mais gosto, com base nos critérios acima. Obviamente, incentivo todos os outros a votarem em suas soluções favoritas aqui também.
Nota sobre prazo
Este concurso será realizado até que a recompensa acabe, cerca das 18h no sábado, 30 de maio. Não sei dizer a hora exata em que terminará; pode estar entre as 17 e as 19h. Garantirei que examinarei todas as entradas enviadas até as 14h e farei o possível para ver todas as entradas enviadas até as 16h; se as soluções forem enviadas depois disso, talvez eu não tenha chance de dar uma olhada justa antes de tomar minha decisão. Além disso, quanto mais cedo você enviar, mais chances terá de votar para poder me ajudar a escolher a melhor solução. Portanto, tente enviá-lo mais cedo do que no prazo.
Notas Unicode
Também houve alguma confusão sobre exatamente quais caracteres Unicode são permitidos. O intervalo de possíveis pontos de código Unicode é U+0000
para U+10FFFF
. Existem alguns pontos de código que nunca são válidos para uso como caracteres Unicode em qualquer intercâmbio aberto de dados; esses são os não caracteres e os pontos de código substitutos . Noncharacters são definidos no 5.1.0 secção Unidode Norma 16.7 como os valores U+FFFE
, U+FFFF
, U+
nFFFE
, U+
nFFFF
, onde n é 1
- 10
hexadecimal, e a gama U+FDD0
-U+FDEF
. Esses valores devem ser usados para uso interno específico do aplicativo, e os aplicativos em conformidade podem retirar esses caracteres do texto processado por eles. Pontos de código substitutos, definidos na seção 3.8.0 do Unicode Standard 3.8 como U+D800
- U+DFFF
, são usados para codificar caracteres além do Plano Multilíngue Básico em UTF-16; portanto, é impossível representar esses pontos de código diretamente na codificação UTF-16 e é inválido codificá-los em qualquer outra codificação. Assim, para os fins deste concurso, permitirei que qualquer programa que codifique imagens em uma sequência de no máximo 140 pontos de código Unicode do intervalo U+0000
- U+10FFFF
excluindo todos os não caracteres e pares substitutos, conforme definido acima.
Vou preferir soluções que usam apenas caracteres atribuídos, e melhor ainda aqueles que usam subconjuntos inteligentes de caracteres atribuídos ou fazer algo interessante com o conjunto de caracteres que eles usam. Para obter uma lista dos caracteres atribuídos, consulte o banco de dados de caracteres Unicode ; observe que alguns caracteres são listados diretamente, enquanto outros são listados apenas como o início e o fim de um intervalo. Observe também que os pontos de código substitutos estão listados no banco de dados, mas são proibidos conforme mencionado acima. Se você quiser tirar proveito de certas propriedades dos caracteres para tornar o texto que você produz mais interessante, há uma variedade de bancos de dados com informações sobre caracteres , como uma lista de blocos de código nomeados e várias propriedades de caracteres.
Como o Twitter não especifica exatamente o conjunto de caracteres que eles suportam, serei indulgente com soluções que não funcionam com o Twitter porque certos caracteres contam caracteres extras ou extra. É preferível, mas não obrigatório, que todas as saídas codificadas possam ser transferidas ilesas via Twitter ou outro serviço de microblog, como o identi.ca . Eu vi alguma documentação declarando que o Twitter codifica a entidade <,> e &, e, portanto, conta esses caracteres como 4, 4 e 5, respectivamente, mas eu não testei isso sozinho, e o contador de caracteres JavaScript não parece contá-los dessa maneira.
Dicas e Links
- A definição de caracteres Unicode válidos nas regras é um pouco complicada. A escolha de um único bloco de caracteres, como os Ideógrafos Unificados CJK (U + 4E00 – U + 9FCF), pode ser mais fácil.
- Você pode usar bibliotecas de imagens existentes, como ImageMagick ou Python Imaging Library , para sua manipulação de imagens.
- Se você precisar de ajuda para entender o conjunto de caracteres Unicode e suas várias codificações, consulte este guia rápido ou esta FAQ detalhada sobre UTF-8 no Linux e Unix .
- Quanto mais cedo você encontrar sua solução, mais tempo eu (e outras pessoas votando) terei de analisá-la. Você pode editar sua solução se a melhorar; Baseará minha recompensa na versão mais recente quando der minha última olhada nas soluções.
- Se você deseja que um formato de imagem fácil seja analisado e gravado (e não queira usar apenas um formato existente), sugiro usar o formato PPM . É um formato baseado em texto muito fácil de trabalhar, e você pode usar o ImageMagick para converter para e a partir dele.