Comprimere il codice in un'immagine


17

Si tratta di una variazione.

introduzione

Abbiamo tutto il codice breve di scrittura, perché alcuni motivi oscuri , ma qualunque cosa facciamo, the'll occupano almeno 144 pixel / byte (con un font 12px). Ma cosa sarebbe successo, se vogliamo codificare il nostro codice nelle immagini? Questo è il vostro compito oggi.

Sfida

È compito è quello di leggere nel codice sorgente proprio (quines non corrette sono consentiti, ad esempio, letteralmente la lettura del file di origine), e creare un'immagine fuori di esso, impostando i componenti rosso, verde e blu di un pixel in base al ASCII valore del carattere.

Esempio:

Abbiamo la stringa "Ciao mondo!"

Hello world!

Cerchiamo di convertire questo in valori ASCII:

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

Mappa i valori RGB ad esso (se la lunghezza del codice sorgente non è divisibile per 3, 0s utilizzare come caratteri rimanenti):

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

Quindi creiamo l'immagine con l'area più piccola al di fuori di essa. Abbiamo 4 set di valori RGB, quindi l'immagine più piccola sarà un'immagine di 2 * 2, che va dall'alto a sinistra pixel a destra:

inserisci qui la descrizione dell'immagine

E otteniamo questa immagine terribilmente colorato (ridimensionata, quindi è almeno visibile, dimostra anche il fatto quanto piccolo si può ottenere)

Regole / Ulteriori informazioni

  • Non c'è alcun ingresso
  • L'output deve essere un file separato o in una finestra separata.
  • Per i caratteri multibyte, dividere il personaggio in 2 byte.
  • Il codice sorgente deve essere di almeno 1 byte lungo
  • L'immagine dovrebbe essere quella delle dimensioni possibili, che ha il rapporto larghezza / altezza più vicino a 1
  • Il conteggio dei pixel sull'immagine dovrebbe essere esattamente ceil (numero di byte / 3), dovrebbero essere aggiunti senza pixel in più

punteggio

Questo è un , quindi vince la risposta più piccola in byte.


7
In attesa di una sottomissione Piet ...: P
Rɪᴋᴇʀ

3
Che cosa è "l'immagine più piccola"? Il più piccolo zona? Non sarebbe sempre una linea retta? Il soggetto inquadrato deve essere quadrata? Se è così, come possiamo pad pixel che non si adattano in piazza? Potrebbe fornire alcune soluzioni di esempio? (Non necessariamente con il codice sorgente, qualsiasi stringa)
DJMcMayhem

2
Ancora non è libero eccellente. Che è più importante, un'area più piccola, o la larghezza minima al rapporto heighth? E se fosse stato a tre, o qualsiasi altro numero primo di pixel? Devo fare 1x3 (area più piccola) o 2x2 con un pixel mancante (rapporto più piccolo)? Che cosa dovrebbe quel pixel mancante essere?
DJMcMayhem

3
Era sulla sandbox? Sembra che avrebbe potuto usare un po 'di tempo lì.
Morgan Thrapp,

1
Non è il più piccolo rapporto larghezza / altezza tecnicamente sarà sempre height = Ne width = 1? Penso che intendi larghezza / altezza più vicina a 1.
Suever

Risposte:


1

In realtà, 12 byte

Q"P6 4 1 255

Provalo online!

Questo programma funziona anche seriamente.

Questo programma emette un immagine PPM , che è accettabile per default .

immagine di output (scalati 50x):

produzione

Spiegazione:

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: L'output dovrebbe essere come un file separato . Non ritiene questo solo l'output del file contenuti su STDOUT?
Adám

8

MATLAB, 81 72 69 byte

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

Questo crea una funzione anonima che può essere incollata nella finestra di comando ed eseguita utilizzando ans(). Quando eseguire questo crea un'immagine di 23 pixel (un primo) pertanto la rappresentazione più quadrato è un semplice array di pixel.

inserisci qui la descrizione dell'immagine

Spiegazione

Se incollata nella finestra di comando, la funzione anonima si assegnerà automaticamente alla variabile ans. Quindi all'interno della funzione anonima, utilizziamo:

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

che valuta char(ans)all'interno del namespace della finestra di comando, piuttosto che all'interno del namespace locale della funzione anonima. È quindi in grado di convertire la funzione anonima stessa in una rappresentazione di stringa.

Quindi abbiamo le seguenti operazioni che sono più semplici:

%// 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 per l' ansidea!
flawr

Questo non è necessario eseguire due volte per lavoro? La prima volta intorno, mi aspetto che per creare un'immagine in base al valore ansha fino alla prima corsa è stata completata, che si traduce in ansdivenire la funzione stessa. La seconda volta che usa "proprio" codice (bene davvero, è il codice di una funzione anonima separati ma identici). Detto questo, non so MATLAB, quindi potrei sbagliarmi.
Adám

2
@ Nᴮᶻ Questa è la bellezza di usare evalinper chiamare char(ans)nell'area di lavoro di base. L' evalinviene valutato solo in fase di esecuzione , quindi anche se ansnon è definito quando si incolla nella finestra di comando, quando si chiama ans()per eseguire questa funzione anonima, ans è definito e la evalinchiamata all'interno della funzione anonima può accedervi. Quindi non è necessario eseguirlo due volte. Se potessi contare sul fatto che sarebbe stato eseguito due volte, evalin('base', 'char(ans)')sarebbe stato sostituito semplicementechar(ans)
Suever,

4

Javascript (ES6) 324 312 309 byte

Sono sicuro che questo potrebbe essere giocato un po 'a golf:

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'))}
  • crea una tela
  • costruisce l'immagine in esso
  • Apre l'URL dei dati per l'immagine in una nuova scheda

Nuove linee per la leggibilità:

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

Produzione

JavaScript


Dato che non l'ho specificato, non è necessario eseguirlo automaticamente.
Bálint,

Inoltre, basta inserire una variabile fittizia invece di usare paragrafi vuoti
Bálint,

Paragrafi vuoti? Dove?
Shaun H,

f=()=>{Qui, basta fare f=_=>, -1 byte, basta non usarlo, javascript è debolmente tipizzato
Bálint

Parametri Ah, corrente lasciando le parentesi è più conveniente che la gestione non divisibile per 3
Shaun H

3

Javascript ES6 - 216 byte

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

Nota: frestituisce una tela.

Esempio di esecuzione (presuppone che sia <body>necessario aggiungere un):

document.body.appendChild(f())

Dovrebbe scaricare la seguente immagine sulla pagina (ingrandita):

QuineImage


L'ultima pixel è completamente vuota, si può fare, quindi è 71 pixel in totale?
Bálint

@ Bálint Whoops, non vedere la parte pixel vuoto. È interessante notare che, se provo a fare l'71x1 immagine, che aumenta il mio numero di byte a 214 e tra l'altro, il numero di pixel a 72, che è 9x8, che a sua volta porta il numero di byte di nuovo a 213. Si rovina anche il calcolo canale alfa . L'attuale soluzione più pulita che soddisfa tutti i requisiti è quella di aggiungere 3 caratteri ridondanti alla soluzione ...
Dendrobium,

2

PowerShell v4, 64 byte

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

Si ottiene il contenuto del proprio nome, getta la stringa come un array di caratteri, aggiunge alcune intestazione PPM e imposta il contenuto di a.ppm come uscita. 64 byte rende 11x2 pixel:

fonte PowerShell codificato come immagine


1

Node.JS, 63 byte

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

Uscite immagine in un file di nome P6che si trova nel PPM formato (P6).

Ecco una resa PNG (7x3 pixel):

inserisci qui la descrizione dell'immagine


1

PHP, 226 byte

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

versione Ungolfed

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

Inserisci questo script in un file chiamato 'p.php' ed eseguilo. È necessario il proprio metodo di esecuzione dello script PHP, perché questo legge da un file locale.

Immagine di uscita:

codice colore


0

Caratteri Java 511

La lunghezza della soluzione porta ad un quadro più grande che è fresco, perché queste immagini sono veramente bello.

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

Si noti che non v'è un ritorno a capo finale invisibile! E 'legge il file di origine, che deve essere "Q.java" e crea un'immagine "Q.png" che assomiglia a questo:

L'immagine generata dal codice

o ridimensionato 100x inserisci qui la descrizione dell'immagine


0

APL (Dyalog) , 33 byte

Richiede il ⎕IO←0valore predefinito su molti sistemi. Inoltre, AutoFormat deve essere spento per conservare il programma esattamente come indicato.

(⊂⎕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

Crea P: P3 1 255 185 11 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
cui si salva e rilasciare qui per vedere:L'immagine del codice

⎕NR'f'N ressata R ePresentation del programma f

⊃⌽ seleziona l'ultimo (acceso. primo dell'elemento invertito) (linea)

'␍ɫ␉⍣', anteporre i quattro caratteri (tipo di file, larghezza, altezza, max)

⎕AV⍳ trovare indici corrispondenti nella A Tomic V ector (set di caratteri

 formatta come testo

'P', anteporre una lettera

(... ) applica la seguente funzione tacita:

 prendi l'intero argomento [e in a]

⎕NPUTN ative [file,] Put [it, con un nome file composto da]

 il primo carattere ("P")


Che cosa significa questo tabella codici assumere?
Bálint

@ Bálint Vedi modifica.
Adám,

Come mai l'immagine risultante è di 42 pixel invece di 14? Questo perché i tuoi "byte" corrispondono a caratteri multibyte?
Suever,

@Suever Fixed. Grazie.
Adám,

A proposito, penso, se la versione aveva un compilatore prima della sfida, allora è legale.
Bálint,

-1

Python, 81 byte

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

L'output è in formato PPM.

Ecco come appare l'immagine:

Immagine

Aggiustato in proporzione:

Aggiustato in proporzione


Non ti vedo riutilizzareq
Maltysen,

Se si utilizza il P6formato, non è necessario convertire in ordinali. Inoltre, per RGB a 8 bit, 255dovrebbe essere usato al posto di 256.
Mego

Se lo usi solo quna volta, come sembra, elimina il compito e lo sostituisci direttamente: ti farà risparmiare tre byte.
Fondi Monica's Lawsuit

Sembra che tu stampi il contenuto del file, ma OP ha detto che l'output dovrebbe essere un file separato .
Adám,

Ciao, @QPaysTaxes detto print'P3\n9 3 256 '+' '.join(map(lambda x:str(ord(x)),open(__file__).read())). Sono -4 byte, però!
Erik the Outgolfer
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.