如果一张图片的价值为1000字,那么您可以用140个字符容纳多少张图片?
注意:就是这样!赏金的截止日期已经到了,经过一番艰苦的考虑之后,我认为Boojum的入场机会刚好超出Sam Hocevar的入场机会。一旦有机会将它们写下来,我将发布更详细的注释。当然,每个人都应随时继续提交解决方案并改进解决方案以供人们投票。感谢所有提交和输入的人;我都喜欢。对我来说,这很有趣,我希望对参赛者和观众来说都很有趣。
我遇到了一篇有关尝试将图像压缩到Twitter评论中的有趣文章,并且该线程(以及Reddit上的一个线程)中的很多人都提出了有关您可以采用的不同方法的建议。因此,我认为这将是一个很好的编码挑战;让人们把钱花在嘴上,并展示他们的编码思想如何在有限的可用空间内带来更多细节。
我挑战您提出一个通用系统,该系统可将图像编码为140个字符的Twitter消息,然后再次将其解码为图像。您可以使用Unicode字符,因此每个字符可获得8位以上的字符。但是,即使允许使用Unicode字符,您也需要将图像压缩到很小的空间中。这肯定是有损压缩,因此必须对每个结果的外观有主观判断。
这是原始作者Quasimondo从他的编码中获得的结果(图像已获得知识共享署名-非商业许可):
你能做得更好吗?
规则
- 您的程序必须具有两种模式:编码和解码。
- 当编码:
- 您的程序必须以您选择的任何合理的栅格图形格式输入图形。我们将说ImageMagick支持的任何栅格格式都算合理。
- 您的程序必须输出一条消息,该消息可以用140个或更少的Unicode代码点表示。在范围140个的代码点
U+0000
-U+10FFFF
,排除非字符(U+FFFE
,U+FFFF
,U+
ÑFFFE
,U+
ÑFFFF
其中Ñ是1
-10
十六进制和范围U+FDD0
-U+FDEF
)和替代代码点(U+D800
-U+DFFF
)。它可能以您选择的任何合理编码输出;GNUiconv
支持的任何编码都将被认为是合理的,并且您的平台本机编码或语言环境编码将是一个不错的选择。有关更多详细信息,请参见下面的Unicode注释。
- 当解码:
- 您的程序应将编码模式的输出作为输入。
- 您的程序必须以您选择的任何合理格式输出图像,如上所述,尽管对于输出矢量格式也可以。
- 图像输出应该是输入图像的近似值;您离输入图像越近越好。
- 除了上面指定的输出,解码过程可能无法访问编码过程的任何其他输出;也就是说,您无法将图像上传到某处并输出URL以供解码过程下载,或者诸如此类的愚蠢行为。
为了保持用户界面的一致性,您的程序必须具有以下行为:
- 您的程序必须是可以在具有适当解释器的平台上设置为可执行文件的脚本,或者是可以编译为可执行文件的程序。
- 您的程序必须将第一个参数设为
encode
或decode
设置模式。 您的程序必须以下列一种或多种方式进行输入(如果实现一种采用文件名的方式,则如果缺少文件名,则也可以从stdin和stdout进行读取和写入):
从标准输入中获取输入,并在标准输出中生成输出。
my-program encode <input.png >output.txt my-program decode <output.txt >output.png
从第二个参数中命名的文件中获取输入,并在第三个参数中命名的文件中产生输出。
my-program encode input.png output.txt my-program decode output.txt output.png
- 为您的解决方案,请发布:
- 您的代码完整和/或托管在其他地方的链接(如果它很长,或者需要编译许多文件等)。
- 如果它在代码中不是立即显而易见的,或者代码很长,人们可能会对摘要感兴趣,请对其进行解释。
- 带有原始图像,压缩后的文本和解码图像的示例图像。
- 如果您是基于其他人的想法,请归因于他们。可以尝试完善其他人的想法,但是您必须将其归因于。
指导方针
这些基本上是可能被打破的规则,建议或评分标准:
- 美学很重要。我将根据以下内容进行判断,并建议其他人进行判断:
- 输出图像看起来有多好,看起来像原始图像多少。
- 文字看起来不错。如果您有一个非常聪明的压缩方案,则完全随机的gobbledigook可以,但是我还想看到将图像转换为多语言诗歌或类似之类的答案。请注意,原始解决方案的作者决定只使用汉字,因为那样看起来更好。
- 有趣的代码和聪明的算法总是好的。我喜欢简短,清晰的代码,但是真正聪明的复杂算法也可以,只要它们能产生良好的结果。
- 速度也很重要,尽管不如一项工作对图像的压缩效果那么重要。我宁愿有一个可以在十分之一秒的时间内转换图像的程序,而不是可以连续几天运行遗传算法的程序。
- 我会更喜欢较短的解决方案,而不是较长的解决方案,只要它们在质量上具有可比性即可。简洁是一种美德。
- 您的程序应使用在Mac OS X,Linux或Windows上可以免费使用的语言来实现。我希望能够运行这些程序,但是如果您有一个仅在MATLAB或其他条件下运行的出色解决方案,那很好。
- 您的程序应尽可能通用。它应该适用于尽可能多的不同图像,尽管某些图像可能比其他图像产生更好的结果。特别是:
- 在程序中内置一些与之匹配并写入引用的图像,然后在解码时生成匹配图像,这是相当la脚的,将仅覆盖一些图像。
- 可以拍摄简单,平坦,几何形状的图像并将其分解为某些矢量基元的程序非常漂亮,但是如果它在超过一定复杂度的图像上失败,则可能不够通用。
- 只能拍摄特定固定长宽比的图像但效果很好的程序也可以,但并不理想。
- 您可能会发现,与彩色图像相比,黑白图像可以在较小的空间中获取更多信息。另一方面,这可能会限制其适用的图像类型;黑白效果很好,但是抽象的设计可能效果不佳。
- 如果输出图像小于输入图像,并且比例大致相同,则完全可以。如果必须放大图像以将其与原始图像进行比较,可以。重要的是外观。
- 您的程序应产生实际上可以通过Twitter发出且毫发无损的输出。这只是一个准则,而不是一条规则,因为我找不到支持的精确字符集的任何文档,但是您应该避免使用控制字符,时髦的不可见组合字符,专用字符等。
评分标准
作为有关如何选择接受的解决方案时如何对解决方案进行排名的一般指南,可以说我可能会以25分制来评估解决方案(这很粗糙,我不会直接得分,仅使用这是基本准则):
- 编码方案可以很好地再现各种输入图像的15分。这是一个主观的审美判断
- 0表示它根本不起作用,每次都返回相同的图像,或类似的东西
- 5表示它可以对一些图像进行编码,尽管解码后的版本看起来很难看,而且在更复杂的图像上可能根本不起作用
- 10表示它可处理各种图像,并产生令人愉悦的图像,有时可能会与众不同
- 15表示它可以生成某些图像的完美副本,甚至对于更大,更复杂的图像,也可以识别出某些内容。或者,也许它不能产生可识别的图像,但是会产生清晰可见于原始图像的精美图像。
- 巧妙使用Unicode字符集需要
3分
- 简单使用整个允许的字符集即可获得0分
- 使用有限的字符集可以安全地通过Twitter或在各种情况下传输的1分
- 使用主题字符子集(例如仅汉文字或仅从右到左字符)获得2分
- 做真正整洁的事情(如生成可读文本或使用看起来像所讨论图像的字符)要3分
- 聪明的算法方法和代码风格获得
3分
- 0点代表1000行代码,仅用于缩小图像,将其视为每个像素1位,然后base64对其进行编码
- 对于使用标准编码技术并且写得很好且简短的内容,要获得1分
- 引入相对新颖的编码技术的东西,或者令人惊讶的短而干净的东西,只需2分
- 对于实际上能产生良好结果或在图形编码中取得新突破的衬里,要获得3分(如果这似乎不足以突破新点,请记住,这种良好的结果在美学上可能会获得高分以及
- 2分的速度。在所有其他条件相同的情况下,速度越快越好,但是上述标准比速度更重要
- 在自由(开源)软件上运行可获得1分,因为我更喜欢自由软件(请注意,只要C#在Mono上运行,C#仍然有资格获得此积分,同样,如果在GNU Octave上运行,MATLAB代码也将具有资格)
- 实际遵守所有规则可得1分。这些规则变得有些复杂,因此我可能会接受否则会给出一个小细节错误的好的答案,但我将对实际上遵循所有规则的任何解决方案给予额外的加分
参考图片
有些人要求提供一些参考图像。以下是一些您可以尝试的参考图片;较小的版本嵌入在此处,如果需要,它们都链接到图像的较大版本:
奖
根据上述标准,我将为我最喜欢的解决方案提供500代表奖金(加上StackOverflow投入的50 奖励)。当然,我也鼓励其他人在这里对自己喜欢的解决方案进行投票。
注意截止日期
这项比赛将一直持续到赏金用完为止,即5月30日(星期六)下午6点左右。可能是下午5点到晚上7点。我将保证我将查看下午2点之前提交的所有条目,并且会尽力查看下午4点之前提交的所有条目;如果在此之后提交解决方案,那么在我必须做出决定之前,我可能没有机会给他们一个公平的外观。另外,您提交的越早,您投票的机会就越多,能够帮助我选择最佳解决方案,因此,请尽早提交,而不是在截止日期之前提交。
Unicode注释
关于允许使用哪些Unicode字符,也存在一些困惑。可能的Unicode代码点范围U+0000
为U+10FFFF
。有些代码点在任何公开的数据交换中都永远无法用作Unicode字符;这些是非字符和替代代码点。Noncharacters在所定义的Unidode标准5.1.0节16.7作为值U+FFFE
,U+FFFF
,U+
ÑFFFE
,U+
ÑFFFF
其中Ñ是1
- 10
十六进制和范围U+FDD0
-U+FDEF
。这些值旨在用于特定于应用程序的内部使用,并且合格的应用程序可能会从这些字符所处理的文本中删除这些字符。替代代码点(在Unicode标准5.1.0第3.8节中定义为U+D800
– U+DFFF
)用于对UTF-16中基本多语言平面之外的字符进行编码;因此,不可能直接以UTF-16编码表示这些代码点,并且以任何其他编码对它们进行编码都是无效的。因此,出于竞赛目的,我将允许任何程序将图像编码成不超过140个Unicode代码点的序列,范围不包括U+0000
- U+10FFFF
上面定义的所有非字符和代理对。
我更喜欢仅使用分配的字符的解决方案,甚至更喜欢使用分配的字符的巧妙子集或对它们使用的字符集做一些有趣的事情的解决方案。有关分配的字符的列表,请参见Unicode字符数据库。请注意,有些字符是直接列出的,而有些字符只是作为范围的开始和结尾列出的。另请注意,代理代码点已在数据库中列出,但如上所述是禁止的。如果您想利用字符的某些属性来使输出的文字更有趣,可以使用多种字符信息数据库,例如命名代码块列表和各种字符属性。
由于Twitter并未指定他们支持的确切字符集,因此我会宽容一些实际上不适用于Twitter的解决方案,因为某些字符会多余或某些字符会被剥离。最好但不要求所有编码的输出都应能够通过Twitter或其他微博客服务(例如identi.ca)无损传输。我看过一些文档,说明Twitter实体对<,>和&进行编码,因此分别将它们分别计数为4、4和5个字符,但我自己尚未对其进行测试,并且它们的JavaScript字符计数器似乎没有用这种方式来计算它们。
提示与链接
- 规则中有效Unicode字符的定义有点复杂。选择单个字符块,例如CJK统一表意文字(U + 4E00–U + 9FCF)可能会更容易。
- 您可以使用现有的图像库(例如ImageMagick或Python Imaging Library)进行图像处理。
- 如果您需要帮助来理解Unicode字符集及其各种编码,请参阅此快速指南或有关Linux和Unix中UTF-8的详细FAQ。
- 您越早获得解决方案,我(和其他投票者)就会花更多的时间研究它。如果您改进解决方案,则可以对其进行编辑;当我最后浏览解决方案时,我将以最新版本为基础。
- 如果您想解析和编写简单的图像格式(并且不想只使用现有格式),建议您使用PPM格式。这是一种基于文本的格式,非常易于使用,您可以使用ImageMagick来回转换。