TransWikia.com

Compress your code in an image

Code Golf Asked by Bálint on August 17, 2020

This is a variation.

Introduction

We all write short code, because some obscure reasons, but whatever we do, the’ll take up at least 144 pixels/byte (with a 12px font). But what would happen, if we would encode our code in images? This is your task today.

Challenge

You task is to read in your own source code (non-proper quines are allowed, e.g. literally reading the source file), and create an image out of it, by setting the red, green and blue components of a pixel based on the ASCII value of the character.

Example:

We have the string "Hello world!"

Hello world!

Let’s convert this to ASCII values:

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

Map the RGB values to it (If the source code’s length is not divisible by 3, use 0s as the remaining characters):

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

We then create the image with the smallest area out of it. We have 4 sets of RGB values, so the smallest image will be a 2*2 image, going from the top left pixel to the right:

enter image description here

And we get this awfully colored image (resized, so it’s at least visible, also proves the fact how small it can get)

Rules/Additional information

  • There’s no input
  • The output should be as a separate file, or in a separate window.
  • For multibyte characters, split the character in 2 bytes.
  • The source code must be at least 1 byte long
  • The image should be the one from the possible sizes, wich has the closest width/height ratio to 1
  • The pixel count on the image should exactly be ceil(byte count / 3), no extra pixels should be added

Scoring

This is a , so the smallest answer in bytes wins.

11 Answers

Actually, 12 bytes

Q"P6 4 1 255

Try it online!

This program also works in Seriously.

This program outputs a PPM image, which is acceptable by default.

Output image (scaled up 50x):

output

Explanation:

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)

Correct answer by Mego on August 17, 2020

Processing, 193 bytes

byte a[]=loadBytes("s.pde");noStroke();int x=0,y=0;for(int k=0;k<a.length%3;k++){append(a,byte(0));}for(int i=0;i<a.length-2;i+=3,x++){if(x>0){x=0;y+=1;}fill(a[i],a[i+1],a[i+2]);rect(x,y,1,1);}

Original

enter image description here

Resized

enter image description here

Even with Processing's builtins, this was very difficult.

Answered by Razetime on August 17, 2020

Java 511 chars

The length of the solution leads to a greater picture which is cool, because these pictures are really nice.

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+='';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"));}}

Note that there is an invisible trailing newline! It reads the source file, which has to be "Q.java" and creates a picture "Q.png" which looks like this:

The image generated by the code

or scaled 100x enter image description here

Answered by Frozn on August 17, 2020

PowerShell v4, 64 bytes

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

It gets the content of its own filename, casts the string as a char array, adds some PPM header and sets the content to a.ppm as output. 64 bytes makes it 11x2 pixels:

PowerShell source encoded as picture

Answered by TessellatingHeckler on August 17, 2020

PHP, 226 bytes

Golfed

<?$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);

Ungolfed version

<?
// 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);

Enter this script into a file named 'p.php' and run it. You need your own method of running PHP script, because this reads from a local file.

Output image:

color coded

Answered by Xanderhall on August 17, 2020

Node.js, 63 bytes

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

Outputs image into a file named P6 which is in the PPM (P6) format.

Here's a PNG rendition (7x3 pixels):

enter image description here

Answered by Mwr247 on August 17, 2020

Python, 81 bytes

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

Output is in PPM format.

This is what the image looks like:

Image

Scaled up:

Scaled up

Answered by Loovjo on August 17, 2020

MATLAB, 81 72 69 bytes

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

This creates an anonymous function which can be pasted into the command window and run using ans(). When run this creates a 23-pixel image (a prime) therefore the most square representation is a simple array of pixels.

enter image description here

Explanation

When pasted into the command window, the anonymous function will automatically assign itself to the variable ans. Then from within the anonymous function, we use:

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

which evaluates char(ans) within the namespace of the command window rather than within the local namespace of the anonymous function. It is therefore able to convert the anonymous function itself into a string representation.

Then we have the following operations which are more straightforward:

%// 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);

Answered by Suever on August 17, 2020

Javascript ES6 - 216 bytes

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)

Ungolfed:

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

Note: f returns a canvas.

Example run (assumes there's a <body> to append to):

document.body.appendChild(f())

Should dump the following image to the page (enlarged):

QuineImage

Answered by Dendrobium on August 17, 2020

APL (Dyalog), 33 bytes

Requires ⎕IO←0 which is default on many systems. Also, AutoFormat should be off to preserve the program exactly as given.

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

Hex 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

Creates P: P3 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
Which you save and drop here to see: code image

⎕NR'f'Nested Representation of the program f

⊃⌽ pick the last (lit. first of the reversed) element (line)

'␍ɫ␉⍣', prepend the four characters (filetype, width, height, max)

⎕AV⍳ find corresponding indices in the Atomic Vector (the character set

 format as text

'P', prepend a letter

() apply the following tacit function:

 take the entire argument [and into a]

⎕NPUTNative [file,] Put [it, with a filename consisting of]

 the first character ("P")

Answered by Adám on August 17, 2020

Javascript(ES6) 324 312 309 Bytes

I'm sure this could be golfed a bit:

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'))}
  • creates a canvas
  • builds image in it
  • Opens data url for image in new tab

New lines for readability:

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'))
}

Output

JavaScript

Answered by Shaun H on August 17, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP