Twitter图像编码挑战[关闭]

梦想的初衷 提交于 2020-01-06 16:11:36

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

如果一张图片价值1000字,你可以在140个字符中放入多少图片?

注意 :那就是大家! 赏金的最后期限就在这里,经过一番艰难的考虑后,我认为Boojum的进入只是勉强淘汰Sam Hocevar的 。 一旦我有机会写下来,我会发布更详细的笔记。 当然,每个人都应该随时继续提交解决方案并改进人们投票的解决方案。 感谢所有提交和参赛的人; 我很喜欢他们。 这对我来说非常有趣,我希望这对参赛者和观众来说都很有趣。

我遇到了一篇关于尝试将图像压缩成Twitter评论的有趣帖子 ,该线程中的很多人(以及Reddit上的一个帖子 )都提出了有关不同方法的建议。 所以,我认为这将是一个很好的编码挑战; 让人们将钱放在嘴边,并展示他们对编码的看法如何在有限的空间中提供更多细节。

我挑战你想出一个通用系统,用于将图像编码成140个字符的Twitter消息,并将它们再次解码为图像。 您可以使用Unicode字符,因此每个字符的字符数超过8位。 但是,即使允许使用Unicode字符,也需要将图像压缩到非常小的空间内; 这肯定会是一种有损压缩,因此必须对每种结果的好看进行主观判断。

以下是原作者Quasimondo从他的编码中获得的结果(图片根据知识共享署名 - 非商业许可证授权 ):

你能做得更好吗?

规则

  1. 您的程序必须有两种模式: 编码解码
  2. 编码时
    1. 您的程序必须以您选择的任何合理光栅图形格式输入图形作为输入。 我们会说ImageMagick支持的任何栅格格式都算合理。
    2. 您的程序必须输出一条消息,该消息可以用140个或更少的Unicode代码点表示; 140个代码点,范围为U+0000 - U+10FFFF ,不包括非字符( U+FFFEU+FFFFU+ n FFFEU+ n FFFF ,其中n1 - 10十六进制,范围为U+FDD0 - U+FDEF )和代理代码点( U+D800 - U+DFFF )。 它可以以您选择的任何合理编码输出; GNU iconv支持的任何编码都被认为是合理的,您的平台本机编码或区域设置编码可能是一个不错的选择。 有关详细信息,请参阅下面的Unicode注释
  3. 解码时
    1. 您的程序应该将编码模式的输出作为输入。
    2. 您的程序必须以您选择的任何合理格式输出图像,如上所述,但输出矢量格式也可以。
    3. 图像输出应该是输入图像的近似值; 越接近输入图像越好。
    4. 除了上面指定的输出之外,解码过程可能无法访问编码过程的任何其他输出; 也就是说,你不能在某处上传图像并输出用于下载的解码过程的URL,或任何类似的傻事。
  4. 为了用户界面的一致性,您的程序必须按如下方式运行:

    1. 您的程序必须是可以在具有相应解释器的平台上设置为可执行的脚本,或者可以编译为可执行文件的程序。
    2. 您的程序必须将第一个参数作为encodedecode来设置模式。
    3. 您的程序必须通过以下一种或多种方式获取输入(如果您实现了带文件名的方法,如果文件名丢失,您也可以从stdin和stdout读取和写入):

      1. 从标准输入获取输入并在标准输出上产生输出。

        my-program encode <input.png >output.txt my-program decode <output.txt >output.png
      2. 从第二个参数中指定的文件中获取输入,并在第三个参数中指定的文件中生成输出。

        my-program encode input.png output.txt my-program decode output.txt output.png
  5. 对于您的解决方案,请发布:
    1. 你的代码,完整的,和/或在其他地方托管的链接(如果它很长,或者需要很多文件来编译,或者其他东西)。
    2. 解释它是如何工作的,如果代码中不是很明显,或者代码很长,人们会对摘要感兴趣。
    3. 示例图像,包含原始图像,压缩到的文本以及解码图像。
    4. 如果您的想法是基于其他人的想法,请归因于他们。 尝试改进别人的想法是可以的,但你必须归因于他们。

方针

这些基本上是可能被破坏的规则,建议或评分标准:

  1. 美学很重要。 我将评判,并建议其他人判断,基于:
    1. 输出图像看起来有多好,它看起来像原始图像。
    2. 文字看起来有多好看。 如果你有一个非常聪明的压缩方案,完全随机的gobbledigook是好的,但我也希望看到将图像变成多语言的答案,或者像这样聪明的东西。 请注意,原始解决方案的作者决定只使用中文字符,因为它看起来更好。
    3. 有趣的代码和聪明的算法总是很好。 我喜欢简短,重点和清晰的代码,但只要它们产生良好的结果,真正聪明的复杂算法也可以。
  2. 速度也很重要,但不如压缩你做的图像的工作有多重要。 我宁愿有一个程序可以在十分之一秒内转换图像,而不是几天运行遗传算法的图像。
  3. 我会更喜欢较短的解决方案,只要它们在质量上具有相当的可比性; 简洁是一种美德。
  4. 您的程序应该使用在Mac OS X,Linux或Windows上具有可自由实现的实现的语言来实现。 我希望能够运行这些程序,但如果你有一个只能在MATLAB下运行的优秀解决方案,那很好。
  5. 你的计划应该尽可能一般; 它应该适用于尽可能多的不同图像,尽管有些图像可能比其他图像产生更好的结果。 特别是:
    1. 将一些内置于程序中的图像与其匹配并写入引用,然后在解码时生成匹配图像,相当蹩脚,并且仅覆盖少量图像。
    2. 一个可以拍摄简单,平面,几何形状的图像并将它们分解成一些矢量图形的程序非常漂亮,但是如果它在超出一定复杂度的图像上失败则可能不够通用。
    3. 一个程序只能拍摄特定固定宽高比的图像,但能很好地使用它们也可以,但不理想。
    4. 您可能会发现黑白图像可以在比彩色图像更小的空间中获得更多信息。 另一方面,这可能会限制它适用的图像类型; 黑色和白色的面孔很好,但抽象的设计可能不会那么好。
    5. 如果输出图像小于输入,则完全没有问题,而大致相同的比例。 如果您必须将图像缩放以将其与原始图像进行比较,则可以。 重要的是它的外观。
  6. 你的程序应该产生的输出实际上可以通过Twitter并且毫发无伤。 这只是一个指导而不是规则,因为我找不到任何支持的精确字符集的文档,但你应该避免控制字符,时髦的隐形组合字符,私人使用字符等。

得分量规

作为我在选择我接受的解决方案时如何对解决方案进行排名的一般指南,让我说我可能会以25分的比例评估解决方案(这非常粗糙,我不会直接评分任何东西,只是使用这是一个基本准则):

  • 15点表示编码方案如何再现各种输入图像。 这是一种主观的审美判断
    • 0表示它根本不起作用,每次都会返回相同的图像,或者其他东西
    • 5意味着它可以编码一些图像,虽然解码版本看起来很丑,但在更复杂的图像上它可能根本不起作用
    • 10意味着它适用于各种图像,并产生令人愉悦的图像,偶尔可以区分
    • 15意味着它可以生成一些图像的完美复制品,即使对于更大和更复杂的图像,它也能提供可识别的东西。 或者,它可能不会使图像具有很强的识别性,但会产生明显来自原始图像的精美图像。
  • 聪明地使用Unicode字符集3分
    • 简单地使用整组允许的字符为0分
    • 1点使用一组有限的字符,这些字符可以安全地通过Twitter或更广泛的情况进行传输
    • 使用主题字符子集的2分,例如仅汉字表意文字或仅从右到左字符
    • 做一些非常整洁的事情需要3分,例如生成可读文本或使用看起来像有问题的图像的字符
  • 聪明的算法方法和代码风格有3个点
    • 只有1000行代码的0分才能缩小图像,将其视为每像素1位,而base64编码为
    • 对于使用标准编码技术并且写得很好并且简短的东西的1分
    • 对于引入相对新颖的编码技术或者令人惊讶的短而干净的东西的2分
    • 实际上可以产生良好效果的一个衬垫有3个点,或者在图形编码方面突破新领域的东西(如果这看起来像是一个很少的分数用于突破新的领域,请记住,这个优点可能会对美学产生高分以及)
  • 2分的速度。 在其他条件相同的情况下,速度越快越好,但上述标准都比速度更重要
  • 在免费(开源)软件上运行1分 ,因为我更喜欢免费软件(请注意,只要它在Mono上运行,C#仍然符合此要求,如果在GNU Octave上运行,MATLAB代码也是合格的)
  • 实际遵守所有规则的1分 。 这些规则变得有点大而复杂,所以我可能会接受其他好的答案,这会让一个小细节错误,但我会给任何实际遵循所有规则的解决方案额外的一点

参考图片

有些人要求提供一些参考图像。 以下是一些您可以尝试的参考图像; 这里嵌入了较小的版本,如果您需要,它们都链接到更大版本的图像:

根据上述标准,我提供了500个代表奖金 (加上StackOverflow推出的50个奖励 ),用于我最喜欢的解决方案。 当然,我也鼓励其他人在这里投票选出他们最喜欢的解决方案。

关于截止日期的说明

这场比赛将持续到赏金用完,即5月30日星期六下午6点左右。我不能说它将结束的确切时间; 它可能是从下午5点到7点。 我保证我会查看下午2点提交的所有参赛作品,我会尽力查看下午4点提交的所有参赛作品; 如果在此之后提交解决方案,我可能没有机会在我做出决定之前给他们一个公平的看法。 此外,您提交的越早,您投票的机会就越大,可以帮助我选择最佳解决方案,因此请尽早提交,而不是在截止日期前提交。

Unicode注释

究竟是什么允许Unicode字符也存在一些混淆。 可能的Unicode代码点范围是U+0000U+10FFFF 。 在任何开放的数据交换中,有一些代码点永远无法用作Unicode字符; 这些都是noncharacters代理代码点 。 Noncharacters在所定义的Unidode标准5.1.0节16.7为值U+FFFEU+FFFFU+ Ñ FFFEU+ Ñ FFFF ,其中n1 - 10十六进制和范围U+FDD0 - U+FDEF 。 这些值旨在用于特定于应用程序的内部使用,并且符合要求的应用程序可能会将这些字符从它们处理的文本中删除。 代理点代码点在Unicode标准5.1.0第3.8节中定义为U+D800 - U+DFFF ,用于编码UTF-16中基本多语言平面之外的字符; 因此,不可能直接在UTF-16编码中表示这些代码点,并且在任何其他编码中对它们进行编码是无效的。 因此,为了本次比赛的目的,我将允许任何编码图像的程序从U+0000 - U+10FFFF范围内不超过140个Unicode代码点的序列,不包括上面定义的所有非字符和代理对。

更喜欢只使用指定字符的解决方案,甚至更喜欢使用指定字符的聪明子集或使用他们使用的字符集做一些有趣事情的解决方案。 有关指定字符的列表,请参阅Unicode字符数据库 ; 请注意,某些字符是直接列出的,而有些字符仅列为范围的开头和结尾。 另请注意,代理代码点列在数据库中,但如上所述是禁止的。 如果您希望利用字符的某些属性来使输出的文本更有趣,则可以使用各种字符信息数据库 ,例如命名代码块列表各种字符属性

由于Twitter没有指定他们支持的确切字符集,因此我会对那些实际上不适用于Twitter的解决方案感到宽容,因为某些字符会计算额外的或某些字符被剥离。 优选但不要求所有编码输出应该能够通过Twitter或其他微博服务(例如identi.ca)无损地传输。 我已经看到一些文档声明Twitter实体编码<,>和&,因此分别计算为4个,4个和5个字符,但我没有自己测试过,他们的JavaScript字符计数器似乎没有以那种方式来统计他们。

提示和链接

  • 规则中有效Unicode字符的定义有点复杂。 选择单个字符块,例如CJK统一表意文字(U + 4E00-U + 9FCF)可能更容易。
  • 您可以使用现有的图像库(如ImageMagickPython Imaging Library )进行图像处理。
  • 如果您需要一些帮助来理解Unicode字符集及其各种编码,请参阅本快速指南有关Linux和Unix中UTF-8的详细常见问题解答
  • 越早获得解决方案,我(以及其他人投票)就必须有更多时间来查看它。 如果您改进了解,您可以编辑解决方案; 当我最后一次查看解决方案时,我将以最新版本为基础。
  • 如果你想要一个简单的图像格式来解析和写(并且不想只使用现有的格式),我建议使用PPM格式 。 它是一种基于文本的格式,非常易于使用,您可以使用ImageMagick进行转换。

#1楼

这种压缩很好。

http://www.intuac.com/userport/john/apt/

http://img86.imageshack.us/img86/4169/imagey.jpg http://img86.imageshack.us/img86/4169/imagey.jpg

我使用了以下批处理文件:

capt mona-lisa-large.pnm out.cc 20
dapt out.cc image.pnm
Pause

生成的文件大小为559个字节。


#2楼

关于此挑战的编码/解码部分。 base16b.org是我尝试指定一种标准方法,用于在更高的Unicode平面中安全有效地编码二进制数据。

一些功能:

  • 仅使用Unicode的私有用户区
  • 每个字符最多可编码17位; 效率几乎是Base64的三倍
  • 提供了编码/解码的参考Javascript实现
  • 包括一些示例编码,包括Twitter和Wordpress

对不起,这个答案对于原始比赛来说太晚了。 我独立于这篇文章开始了这个项目,我在其中发现了一半。


#3楼

好吧,我已经迟到了,但不过我做了我的项目。

这是一种玩具遗传算法,它使用半透明的彩色圆圈来重建初始图像。

特征:

  • 纯净的Lua。 运行Lua解释器运行的任何地方。
  • 使用netpbm P3格式
  • 附带一套全面的单元测试
  • 保留原始图像大小

误的feautres:

  • 在该空间限制下,它仅保留初始图像的基本颜色方案和其几个特征的一般轮廓。

这是一个代表莉娜的例子:犭杨谷杌蒝螦匘匘匮匮匮匮匮刀刀刀刀刀刀刀嚎嚎嚎嚎嚎嚎嚎嚎嚎嚎嚎婊婊婊婊婊婊婊婊婊婊婊裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆裆岂掂戆耔攋斘眐奡萛狂昸箆亲嬎廙栃兡塅受橯恰应戞优猫僘莹吱赜卣朸杈腠綍蝘猕屐称悡诟来噩压罍尕熚帤厥虤嫐虲兙罨縨炘排叁抠堃从弅慌螎熰标宑箫柢橙拃丨蜊缩昔傥舭励癳冂囤璟彔榕兠摈侑蒖孂埮槃姠璐哠眛嫡琠枀訜苄暬厇廪焛瀻严啘刱垫仔

该代码位于bitbucket.org的Mercurial存储库中。 查看http://bitbucket.org/tkadlubo/circles.lua


#4楼

想法:你能用字体作为调色板吗? 尝试在一系列向量中打破图像,试图用向量集的组合来描述它们(每个字符本质上是一组向量)。 这是使用字体作为字典。 例如,我可以使用al作为垂直线,使用 - 作为水平线? 只是一个想法。


#5楼

我的解决方案的一般概述是:

  1. 我首先计算可以容纳140个utf8字符的最大原始数据量。
    • (我假设utf8,这是原始网站声称twitter存储它的消息。这不同于上面的问题陈述,它要求utf16。)
    • 使用这个utf8 faq ,我计算出你可以在一个utf8字符中编码的最大位数是31位。 为此,我将使用U-04000000-U-7FFFFFFF范围内的所有字符。 (1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx,有31 x,因此我可以编码最多31位)。
    • 31位乘以140个字符等于4340位。 将其除以8得到524.5,然后将其舍入为542字节
    • (如果我们将自己限制为utf16,那么我们每个字符只能存储2个字节,这相当于280个字节)。
  2. 使用标准jpg压缩缩小图像。
    • 将图像大小调整为大约50x50px,然后尝试以各种压缩级别压缩它,直到您有一个尽可能接近542字节的图像而不会过去。
    • 这是 mona lisa压缩到536字节的一个例子
  3. 将压缩图像的原始位编码为utf-8字符。
    • 将以下字节中的每个x替换为:1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx,以及图像中的位。
    • 这部分可能是需要编写大部分代码的部分,因为目前没有任何代码可以执行此操作。

我知道你要求代码,但我真的不想花时间来实际编写代码。 我认为有效的设计至少可以激励其他人编写代码。

我认为我提出的解决方案的主要好处是它正在尽可能多地重用现有技术。 尝试编写一个好的压缩算法可能很有趣,但确保有更好的算法,很可能是由拥有更高数学学位的人编写的。

另一个重要的注意事项是,如果确定utf16是首选编码,那么这个解决方案就会崩溃。 压缩到280字节时,jpegs不能正常工作。 虽然,对于这个特定的问题陈述,可能有比jpg更好的压缩算法。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!