注意:就是这样了!赏金截止日期已经到了,在经过一些艰难的考虑后,我已经决定Boojum的参赛作品仅仅超过了Sam Hocevar的。一旦我有机会写下详细的笔记,我将发布更多详细信息。当然,每个人都应该随意提交解决方案,并改进供人们投票的解决方案。感谢所有提交和参与的人;我喜欢他们所有人。对我来说,这是一次很有趣的运行,我希望对参赛者和观众来说也是如此。
我看到了这篇有趣的文章,关于尝试将图像压缩成Twitter评论,那个线程中有很多人(以及Reddit上的一个线程)提出了不同的建议,你可以用不同的方式来做。所以,我认为这将是一个很好的编码挑战;让人们把钱放在嘴巴里,展示他们关于编码的想法如何导致在有限的空间中获得更多的细节。
我向你发起挑战,设计一种通用的系统,将图像编码为 140 个字符的 Twitter 消息,并将其解码为图像。您可以使用 Unicode 字符,因此每个字符可以获得超过 8 位。然而,即使允许使用 Unicode 字符,您仍需要将图像压缩到非常小的空间中;这肯定是有损压缩,因此必须对每个结果看起来好坏做出主观判断。
以下是原始作者 Quasimondo 从他的编码中获得的结果(该图像的许可证为 Creative Commons Attribution-Noncommercial license): 你能做得更好吗?
规则:
- Your program must have two modes: encoding and decoding.
- When encoding:
- Your program must take as input a graphic in any reasonable raster graphic format of your choice. We'll say that any raster format supported by ImageMagick counts as reasonable.
- Your program must output a message which can be represented in 140 or fewer Unicode code points; 140 code points in the range
U+0000
–U+10FFFF
, excluding non-characters (U+FFFE
,U+FFFF
,U+
nFFFE
,U+
nFFFF
where n is1
–10
hexadecimal, and the rangeU+FDD0
–U+FDEF
) and surrogate code points (U+D800
–U+DFFF
). It may be output in any reasonable encoding of your choice; any encoding supported by GNUiconv
will be considered reasonable, and your platform native encoding or locale encoding would likely be a good choice. See Unicode notes below for more details.
- When decoding:
- Your program should take as input the output of your encoding mode.
- Your program must output an image in any reasonable format of your choice, as defined above, though for output vector formats are OK as well.
- The image output should be an approximation of the input image; the closer you can get to the input image, the better.
- The decoding process may have no access to any other output of the encoding process other than the output specified above; that is, you can't upload the image somewhere and output the URL for the decoding process to download, or anything silly like that.
For the sake of consistency in user interface, your program must behave as follows:
- Your program must be a script that can be set to executable on a platform with the appropriate interpreter, or a program that can be compiled into an executable.
- Your program must take as its first argument either
encode
ordecode
to set the mode. Your program must take input in one or more of the following ways (if you implement the one that takes file names, you may also read and write from stdin and stdout if file names are missing):
Take input from standard in and produce output on standard out.
my-program encode <input.png >output.txt my-program decode <output.txt >output.png
Take input from a file named in the second argument, and produce output in the file named in the third.
my-program encode input.png output.txt my-program decode output.txt output.png
- For your solution, please post:
- Your code, in full, and/or a link to it hosted elsewhere (if it's very long, or requires many files to compile, or something).
- An explanation of how it works, if it's not immediately obvious from the code or if the code is long and people will be interested in a summary.
- An example image, with the original image, the text it compresses down to, and the decoded image.
- If you are building on an idea that someone else had, please attribute them. It's OK to try to do a refinement of someone else's idea, but you must attribute them.
指南
这些基本上是可以打破的规则、建议或评分标准:
美学很重要。我将评判,并建议其他人根据以下标准进行评判:- 输出图像的外观和与原始图像的相似程度。
- 文本的美观程度。如果您有非常聪明的压缩方案,完全随机的胡言乱语也可以,但我还想看到将图像转换为多语诗歌或类似聪明的答案。请注意,原始解决方案的作者决定仅使用中文字符,因为这样看起来更漂亮。
- 有趣的代码和聪明的算法总是好的。我喜欢简短、简明的代码,但真正聪明复杂的算法也可以,只要它们产生良好的结果。
我更喜欢较短的解决方案而不是较长的解决方案,只要它们在质量上合理可比;简洁是一种美德。
您的程序应该使用在 Mac OS X、Linux 或 Windows 上有免费实现的语言实现。我希望能够运行程序,但如果您有一个只在 MATLAB 或其他某些语言下运行的好解决方案,那也没关系。
您的程序应该尽可能地通用;它应该适用于尽可能多的不同图像,尽管有些图像可能比其他图像产生更好的结果。特别是:
- 程序内置了一些图像,它匹配并写入引用,然后在解码时生成匹配的图像,这相当无聊,并且只涵盖了一些图像。
- 能够将简单、平面、几何形状的图像分解成一些向量基元的程序非常棒,但如果在某种复杂度之外的图像上失败,则可能不够通用。
- 只能处理特定固定长宽比的图像,但对它们处理得很好也可以,但并不理想。
- 黑白图像可以将更多信息压缩到更小的空间中。另一方面,这可能限制了它适用的图像类型;人脸在黑白图像中表现良好,但抽象设计可能不那么出色。
- 输出图像比输入图像小,但比例大致相同是完全可以的。如果必须将图像放大以与原始图像进行比较,则可以。重要的是它的外观。
评分标准
作为选择我接受的解决方案时的一般指南,我将按照25分制来评估解决方案(这只是一个非常粗略的指南,我不会直接给任何东西评分,只是使用它作为基本指导):
- 15分,用于衡量编码方案对各种输入图像的复制效果。这是一种主观的审美判断。
- 0分表示完全无法工作,每次都返回相同的图像,或者其他情况
- 5分表示它可以编码一些图像,尽管解码版本看起来很丑,并且在更复杂的图像上可能根本不起作用
- 10分表示它适用于各种图像,并产生令人愉悦的图像,有时可能是可辨认的
- 15分表示它可以完美地复制某些图像,即使对于更大更复杂的图像,也会给出可识别的东西。或者,它可能不会生成完全可识别的图像,但会生成从原始图像明显派生出来的美丽图像。
- 3分,用于评估Unicode字符集的巧妙使用
- 如果只是使用允许的所有字符,则得0分
- 使用一组安全传输到Twitter或更广泛应用场景的字符,得1分
- 只使用汉字或只使用从右到左的字符等主题子集,得2分
- 通过生成可读文本或使用类似于所讨论的图像的字符等方式,得3分
- 3分,用于评估巧妙的算法方法和代码风格
- 如果只是使用1000行代码来缩小图像,将其视为每个像素1位,并对其进行base64编码,则得0分
- 使用标准编码技术并且代码简洁规范,得1分
- 引入相对较新的编码技术或非常简短干净的代码,得2分
- 使用一行代码实际上可以产生良好结果,或者在图形编码方面开创新局(如果这看起来是一个低分数的点数,记住这种好的结果通常也会在美学方面获得高分数),则得3分
- 2分,用于评估速度。其他条件相同,速度越快越好,但上述标准比速度更重要。
- 1分,用于评估是否在免费(开源)软件上运行,因为我更喜欢免费软件(请注意,只要在Mono上运行,C#仍然有资格获得此分数,同样,如果它在GNU Octave上运行,MATLAB代码也将有资格获得此分数)
- 1分,用于评估是否实际遵守所有规则。这些规则变得有点大而复杂,因此我可能会接受其他方面良好但有一些小细节错误的答案,但对于实际遵守所有规则的解决方案将给予额外的1分。
参考图片
有些人要求提供一些参考图片。以下是几张你可以尝试的参考图片;这里嵌入了较小版本,如果需要,它们都链接到图像的较大版本:
奖励
我提供500分赏金(加上StackOverflow提供的50分),以最符合以上标准的解决方案为获胜者。当然,我鼓励大家在这里投票选出自己最喜欢的解决方案。
截止日期说明
本次比赛将一直持续到赏金用完为止,即5月30日星期六下午6点左右。我无法确定具体结束时间;可能在下午5点至7点之间。我保证会查看所有在下午2点前提交的条目,并尽力查看在下午4点前提交的所有条目;如果解决方案是在那之后提交的,则可能没有机会在做出决定之前公正地审查它们。此外,您提交得越早,就越有机会让投票帮助我选择最佳解决方案,因此请尽量在截止日期之前提交。
Unicode备注
有些人对允许使用哪些Unicode字符存在困惑。可能的Unicode代码点范围是U+0000
到U+10FFFF
。有些代码点在任何开放数据交换中都不能用作Unicode字符,这些是非字符(noncharacters)和代理编码点(surrogate code points)。Unicode标准5.1.0第16.7节将非字符定义为值U+FFFE
,U+FFFF
,U+
nFFFE
,U+
nFFFF
,其中n是十六进制的1
–10
,以及范围U+FDD0
–U+FDEF
。这些值旨在用于应用程序特定的内部使用,并且符合规范的应用程序可以从它们处理的文本中删除这些字符。代理编码点在Unicode标准5.1.0第3.8节中定义为U+D800
–U+DFFF
,用于在UTF-16中编码超出基本多语言平面(Basic Multilingual Plane)的字符;因此,无法直接表示这些代码点,并且在任何其他编码中对其进行编码都是无效的。因此,在本次比赛中,我将允许任何将图像编码为不超过140个Unicode代码点序列的程序,这些代码点来自于范围U+0000
–U+10FFFF
,并排除上述所有非字符和代理对。
由于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进行转换。