压缩图像中的代码


17

这是变化。

介绍

我们都编写了短代码,因为一些晦涩的原因,但是无论我们做什么,都会占用至少144像素/字节(使用12px字体)。但是,如果我们将图像编码为图像,将会发生什么?这是您今天的任务。

挑战

您的任务是读取自己的源代码(允许使用非正确的quines,例如,从字面上读取源文件),并通过基于ASCII设置像素的红色,绿色和蓝色分量来从中创建图像角色的价值。

例:

我们有字符串“ Hello world!”。

Hello world!

让我们将其转换为ASCII值:

72 101 108 108 111 32 119 111 114 108 100 33

将RGB值映射到它(如果源代码的长度不能被3整除,请使用0s作为剩余字符):

 __________________________________________________
| R | G | B || R | G | B || R | G | B || R | G | B |
----------------------------------------------------
|72 |101|108||108|111|32 ||119|111|114||108|100|33 |
----------------------------------------------------

然后,我们创建其中面积最小的图像。我们有4组RGB值,因此最小的图像将是2 * 2图像,从左上像素到右像素:

在此处输入图片说明

我们得到了这张彩色的图像(调整大小后,它至少可见,也证明了它可以变得多么小)

规则/其他信息

  • 没有输入
  • 输出应作为单独的文件或在单独的窗口中。
  • 对于多字节字符,将字符分成2个字节。
  • 源代码必须至少1个字节长
  • 图片应为可能的尺寸,宽度/高度比应最接近1
  • 图像上的像素数应精确为ceil(字节数/ 3),不应添加额外的像素

计分

这是一个,因此以字节为单位的最小答案将获胜。


7
等待皮特提交...:P
Rɪᴋᴇʀ

3
什么是“最小图像”?面积最小?这不总是一条直线吗?图片必须是正方形的吗?如果是这样,我们如何填充不适合正方形的像素?您能否提供一些示例解决方案?(不一定带有源代码,只有任何字符串)
DJMcMayhem

2
仍然不是超级清楚。最小的面积或最小的宽高比​​哪个更重要?如果像素数是三个或其他素数怎么办?我应该做1x3(最小面积)还是2x2像素丢失(最小比例)?该丢失的像素应该是什么?
DJMcMayhem

3
这是在沙盒上吗?好像在那儿已经用了一段时间了。
摩根瑟普

1
从技术上来说最小的宽度/高度比不是总是height = Nwidth = 1吗?我认为您的意思是宽度/高度最接近
1。– Suever

Answers:


1

其实是12个位元组

Q"P6 4 1 255

在线尝试!

该程序也可以在认真地工作。

该程序输出一个PPM图像默认情况下可接受

输出图像(放大50倍):

output

说明:

Q"P6 4 1 255 
Q             push source code
 "P6 4 1 255  push header for a 4x1 raw (type P6) 8-bit PPM image (the closing " is implicitly added at EOF)

2
OP:输出应作为单独的文件。这不只是将文件内容输出到STDOUT吗?
阿达姆,2013年

8

MATLAB, 81 72 69字节

@()image(shiftdim(reshape(evalin('base','char(ans)'),3,1,23)/255,1.))

这将创建一个匿名函数,该函数可以粘贴到命令窗口中并使用来运行ans()。运行时,它将创建一个23像素的图像(质数),因此,最正方形的表示形式是一个简单的像素阵列。

enter image description here

说明

当粘贴到命令窗口中时,匿名函数将自动将自己分配给变量 ans。然后在匿名函数中,我们使用:

evalin('base', 'char(ans)')

char(ans)在命令窗口的名称空间内而不是在匿名函数的本地名称空间内求值。因此,它能够将匿名函数本身转换为字符串表示形式。

然后我们有以下更简单的操作:

%// Reshape the result into a 3 x 1 x 23 matrix where the first dimension is RGB
%// due to column-major ordering of MATLAB
R = reshape(string, 3, 1, 23);

%// Divide the result by 255. This implicitly converts the char to a double
%// and in order for RGB interpreted properly by MATLAB, doubles must be
%// normalized between 0 and 1.
R = R / 255;

%// Shift the dimensions to the left 1 to move the RGB channel values into
%// the third dimension. Note the extra decimal point. This is because it
%// is far shorter to lengthen the code by one byte than to pad the string
%// to give us a length divisible by 3
R = shiftdim(R, 1.);

%// Display the RGB image
image(R);

1
+1这个ans想法!
瑕疵的

这不是必须运行两次才能起作用吗?第一次,我希望它根据值anshas 来创建图像,直到第一次运行完成为止,这将ans成为函数本身。第二次,它使用“自己的”代码(实际上,它是一个单独但相同的匿名函数的代码)。话虽这么说,我不了解MATLAB,所以我可能是错的。
阿达姆,2013年

2
@Nᴮᶻ这就是在基本工作区中evalin调用的美妙之处char(ans)。将evalin仅在评估运行时间因此,即使ans当你打电话是不是当你把它粘贴到命令窗口中定义,ans()运行这个匿名函数,ans 定义和evalin匿名函数内部调用可以访问它。因此,您不必运行两次。如果我可以依靠它运行两次,evalin('base', 'char(ans)')将被简单地替换char(ans)
-Suever

4

使用Javascript(ES6)324个 312 309字节

我敢肯定这可以打一点:

f=()=>{s="f="+f;l=s.length/3;c=document.createElement('canvas');for(i=0;++i<l/i;l%i?0:w=i,h=l/w);c.s=c.setAttribute;c.s("width",w);c.s("height",h);(i=(t=c.getContext('2d')).createImageData(w,h)).data.map((a,b)=>i.data[b]=b%4<3?s.charCodeAt(b-~~(b/4)):255);t.putImageData(i,0,0);open(c.toDataURL('image/png'))}
  • 创建一个画布
  • 在其中建立图像
  • 在新标签页中打开图片的数据网址

可读性的新行:

f=()=>{
    s="f="+f;l=s.length/3;
    c=document.createElement('canvas');
    for(i=0;++i<l/i;l%i?0:w=i,h=l/w);
    c.s=c.setAttribute;
    c.s("width",w);
    c.s("height",h);
    (i=(t=c.getContext('2d')).createImageData(w,h)).data.map((a,b)=>i.data[b]=b%4<3?s.charCodeAt(b-~~(b/4)):255);
    t.putImageData(i,0,0);
    open(c.toDataURL('image/png'))
}

输出量

的JavaScript


正如我未指定的那样,您无需使其自动运行。
巴林特

此外,只需插入而不是使用空段落虚拟变量
巴林特

空段?哪里?
肖恩H

f=()=>{在这里,只要做f=_=>,-1个字节,就不要使用它,javascript是松散类型的
巴林特

啊,参数,当前离开parens的价格比处理不被3整除的价格便宜
Shaun H

3

Javascript ES6-216字节

f=(  )=>((d=(x=(v=document.createElement`canvas`).getContext`2d`).createImageData(v.width=9,v.height=8)).data.set([..."f="+f].reduce((p,c,i)=>(c=c.charCodeAt(0),[...p,...i%3<2?[c]:[c,255]]))),x.putImageData(d,0,0),v)

取消高尔夫:

f=(  )=>(                                           // define function f (extra spaces to account for missing pixel + alpha channel calculation)
 (d=(x=(v=document.createElement`canvas`).          // assign html5 canvas to v
          getContext`2d`).                          // assign graphics context to x
          createImageData(v.width=9,v.height=8)).   // create & assign ImageData to d
                                                    //   set width and height of both d and v
 data.set([..."f="+f].                              // get f's source, convert to array of chars
   reduce((p,c,i)=>(c=c.charCodeAt(0),              // convert char array to int array
                    [...p,...i%3<2?[c]:[c,255]]))), // insert alpha values 255
 x.putImageData(d,0,0),                             // draw source RGBA array to canvas
 v)                                                 // return canvas

注意:f返回画布。

运行示例(假设<body>要追加一个):

document.body.appendChild(f())

应将以下图像转储到页面(放大):

QuineImage


最后一个像素完全为空,您能做到吗,所以总共是71个像素?
巴林特

@Bálint糟糕,没有看到空白像素部分。有趣的是,如果我尝试将图像制作为71x1,这会使我的字节数增加到214,并且顺便说一下,像素数增加到72,即9x8,这反过来又使字节数回到213。这也破坏了alpha通道计算。当前满足所有要求的最干净的解决方案是在解决方案中添加3个多余的字符……
Dendrobium

2

PowerShell v4,64字节

"P6 11 2 255"+[char[]](gc $MyInvocation.MyCommand.Name)|sc a.ppm

它获取自己的文件名的内容,将字符串转换为char数组,添加一些PPM标头并将内容设置为a.ppm作为输出。64字节使其为11x2像素:

PowerShell源编码为图片


1

Node.js,63个字节

(F=x=>require('fs').writeFile('P6','P6 7 3 255 (F='+F+')()'))()

输出图像到一个指定的文件P6是在PPM(P6)格式。

这是PNG格式(7x3像素):

在此处输入图片说明


1

PHP,226字节

打高尔夫球

<?$b=strlen($w=join(file('p.php')));$z=imagecreatetruecolor(5,15);for($c--;++$c<$b+1|$i%3;$i%3?:$a=!imagesetpixel($z,$x%5,(int)$x++/5,$a))$a+=($c<$b?ord($w[$c]):0)*256**(2-$i++%3);header("Content-Type:image/png");imagepng($z);

非高尔夫版本

<?
// Read the file into an array and join it together. Store the length of the resulting string.
$b=strlen($w=join(file('p.php')));

// Create the image. Our file is 226 bytes, 226/3 = 75 = 5 * 15
$z=imagecreatetruecolor(5,15);

// Loop through the script string, converting each character into a pixel.
// Once three characters have been converted, draw the pixel with the converted RGB value and reset the color to 0.
for($c--;++$c<$b+1|$i%3;$i%3?:$a=!imagesetpixel($z,$x%5,(int)$x++/5,$a))$a+=($c<$b?ord($w[$c]):0)*256**(2-$i++%3);

// Tell the program we're sending an image
header("Content-Type:image/png");

// And send it!
imagepng($z);

将此脚本输入到名为“ p.php”的文件中并运行它。您需要自己的运行PHP脚本的方法,因为这是从本地文件读取的。

输出图像:

颜色编码


0

Java 511个字符

解决方案的长度导致了更大的画面,这很酷,因为这些画面非常好。

import java.awt.image.*;import java.io.*;import java.nio.file.*;import javax.imageio.*; public class Q{public static void main(String[]a)throws Throwable{int w=19,h=9;byte[]e=Files.readAllBytes(Paths.get("Q.java"));String t=new String(e);while(t.length()%3!=0)t+='\0';BufferedImage I=new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);int r,c=r=0;for(int i=0;i<t.length();i++){I.setRGB(c,r,255<<24|t.charAt(i)<< 16|t.charAt(++i)<< 8|t.charAt(++i));if(++c==w){c=0;r++;}}ImageIO.write(I,"png",new File("Q.png"));}}

请注意,有一个看不见的尾随换行符!它读取源文件,该文件必须为“ Q.java”,并创建一个图片“ Q.png”,如下所示:

由代码生成的图像

或缩放100倍 在此处输入图片说明


0

APL(Dyalog),33 字节

要求⎕IO←0在许多系统上是默认设置。另外,应关闭“自动套用格式”以完全按照给定的格式保留程序。

(⊂⎕NPUT⊃)'P',⍕⎕AV⍳'␍ɫ␉⍣',⊃⌽⎕NR'f'  

十六进制B9 BA FD 4E 50 55 54 BB F8 0D 50 0D C2 CD FD 41 56 B2 0D 03 0B 01 FF 0D C2 BB C8 FD 4E 52 0D 16 0D
Unicode 28 2282 2395 4E 50 55 54 2283 29 27 50 27 2C 2355 2395 41 56 2373 27 0D 026B 08 2363 27 2C 2283 233D 2395 4E 52 27 66 27

创建PP3 11 1 255 185 186 253 78 80 85 84 187 248 13 80 13 194 205 253 65 86 178 13 3 11 1 255 13 194 187 200 253 78 82 13 22 13
其中保存和丢弃这里看到:代码图片

⎕NR'f'Ñ相关捐资ř程序的epresentation ˚F

⊃⌽ 选择最后一个(点亮。反转的第一个)元素(行)

'␍ɫ␉⍣', 在四个字符之前(文件类型,宽度,高度,最大)

⎕AV⍳ 发现在相应的索引托米奇V厄克托(字符集

 格式化为文本

'P', 前置一封信

() 应用以下默认功能:

 接受整个论点[并纳入]

⎕NPUT本机 [文件,] 放入 [文件名,文件名包括]

 第一个字符(“ P”)


这假设什么代码页?
巴林特

@Bálint参见编辑。
阿达姆,2013年

结果图像为什么是42像素而不是14像素?这是因为您的“字节”对应于多字节字符吗?
Suever

@Suever已修复。谢谢。
阿达姆,2013年

顺便说一句,我认为,如果在挑战之前该版本具有编译器,那么它是合法的。
巴林特

-1

Python,81个字节

q=open(__file__).read()
print'P3\n9 3 256 '+' '.join(map(lambda x:str(ord(x)),q))

输出为PPM格式。

这是图像的样子:

图片

放大:

放大


我没有看到你重用q
Maltysen

如果使用P6格式,则无需转换为普通格式。此外,对于8位RGB,255应使用代替256
Mego

如果您只使用q一次(如您所愿),则取消分配并直接替换它-这样可以为您节省三个字节。
基金莫妮卡的诉讼

看起来您要打印文件内容,但OP表示输出应作为单独的文件
阿达姆,2013年

您好,@QPaysTaxes说print'P3\n9 3 256 '+' '.join(map(lambda x:str(ord(x)),open(__file__).read()))。它是-4个字节!
暴民埃里克(Erik the Outgolfer)'16年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.