Kompres kode Anda dalam gambar

17

Ini adalah variasi .

pengantar

Kita semua menulis kode pendek, karena beberapa alasan yang tidak jelas , tetapi apa pun yang kita lakukan, akan memakan setidaknya 144 piksel / byte (dengan font 12px). Tetapi apa yang akan terjadi, jika kita menyandikan kode kita dalam gambar? Ini adalah tugas Anda hari ini.

Tantangan

Tugas Anda adalah membaca dalam kode sumber Anda sendiri (quine yang tidak tepat diizinkan, misalnya membaca file sumber secara harfiah), dan membuat gambar dari itu, dengan mengatur komponen merah, hijau dan biru dari sebuah piksel berdasarkan ASCII nilai karakter.

Contoh:

Kami memiliki string "Halo dunia!"

Hello world!

Mari kita konversi ini menjadi nilai ASCII:

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

Memetakan nilai RGB ke sana (Jika panjang kode sumber tidak dapat dibagi 3, gunakan 0s sebagai karakter yang tersisa):

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

Kami kemudian membuat gambar dengan area terkecil dari itu. Kami memiliki 4 set nilai RGB, sehingga gambar terkecil adalah gambar 2 * 2, pergi dari piksel kiri atas ke kanan:

masukkan deskripsi gambar di sini

Dan kami mendapatkan gambar yang sangat berwarna ini (diubah ukurannya, jadi setidaknya terlihat, juga membuktikan betapa kecilnya foto ini)

Aturan / Informasi tambahan

  • Tidak ada input
  • Outputnya harus sebagai file terpisah, atau dalam jendela terpisah.
  • Untuk karakter multibyte, bagi karakter menjadi 2 byte.
  • Panjang kode sumber minimal 1 byte
  • Gambar haruslah yang dari ukuran yang mungkin, yang memiliki rasio lebar / tinggi terdekat dengan 1
  • Jumlah piksel pada gambar harus persis ceil (byte count / 3), tidak ada piksel tambahan yang harus ditambahkan

Mencetak gol

Ini adalah , jadi jawaban terkecil dalam byte menang.

Bálint
sumber
7
Menunggu pengiriman Piet ...: P
R
3
Apa itu "gambar terkecil"? Area terkecil? Bukankah ini selalu menjadi garis lurus? Apakah gambar harus persegi? Jika demikian, bagaimana kita membuat piksel yang tidak sesuai di kotak? Bisakah Anda memberikan beberapa solusi sampel? (Tidak harus dengan kode sumber, hanya string apa pun)
DJMcMayhem
2
Masih belum jelas. Mana yang lebih penting, area terkecil, atau rasio lebar dan tinggi terkecil? Bagaimana jika itu tiga, atau jumlah piksel utama lainnya? Haruskah saya melakukan 1x3 (area terkecil) atau 2x2 dengan piksel yang hilang (rasio terkecil)? Bagaimana seharusnya pixel yang hilang itu?
DJMcMayhem
3
Apakah ini di kotak pasir? Sepertinya itu bisa digunakan beberapa waktu di sana.
Morgan Thrapp
1
Bukankah rasio lebar / tinggi terkecil secara teknis akan selalu height = Ndan width = 1? Saya pikir maksud Anda lebar / tinggi paling dekat dengan 1.
Suever

Jawaban:

1

Sebenarnya, 12 byte

Q"P6 4 1 255

Cobalah online!

Program ini juga bekerja di Seriously.

Program ini menghasilkan gambar PPM , yang dapat diterima secara default .

Gambar output (ditingkatkan 50x):

keluaran

Penjelasan:

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)
Mego
sumber
2
OP: Keluaran harus sebagai file terpisah . Bukankah ini hanya menampilkan konten file ke STDOUT?
Adám
8

MATLAB, 81 72 69 byte

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

Ini menciptakan fungsi anonim yang dapat disisipkan ke jendela perintah dan dijalankan menggunakan ans(). Ketika dijalankan ini menciptakan gambar 23-pixel (prima) karena itu representasi paling persegi adalah array piksel sederhana.

masukkan deskripsi gambar di sini

Penjelasan

Ketika disisipkan ke jendela perintah, fungsi anonim akan secara otomatis menempatkan dirinya ke variabel ans. Kemudian dari dalam fungsi anonim, kami menggunakan:

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

yang mengevaluasi char(ans)dalam namespace dari jendela perintah daripada di dalam namespace lokal dari fungsi anonim. Oleh karena itu ia dapat mengubah fungsi anonim itu sendiri menjadi representasi string.

Kemudian kami memiliki operasi berikut yang lebih mudah:

%// 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);
Suever
sumber
1
+1 untuk ansgagasan itu!
cacat
Tidakkah ini harus dijalankan dua kali untuk bekerja? Pertama kali, saya akan berharap untuk membuat gambar berdasarkan nilai yang ansdimiliki sampai proses pertama selesai, yang menghasilkanans fungsi itu sendiri. Kali kedua, ia menggunakan kode "sendiri" (sebenarnya, itu adalah kode fungsi anonim yang terpisah tapi identik). Yang sedang berkata, saya tidak tahu MATLAB, jadi saya mungkin salah.
Adám
2
@ Nᴮᶻ Itulah keindahan menggunakan evalinuntuk menelepon char(ans)di ruang kerja dasar. The evalinhanya dievaluasi pada saat run-time sehingga meskipun anstidak didefinisikan ketika Anda sisipkan ke jendela perintah, ketika Anda menelepon ans()untuk menjalankan fungsi anonim ini, ans adalah didefinisikan dan evalinpanggilan dalam fungsi anonim dapat mengaksesnya. Jadi Anda tidak harus menjalankannya dua kali. Jika saya bisa mengandalkannya sedang dijalankan dua kali, evalin('base', 'char(ans)')akan digantikan oleh cukupchar(ans)
Suever
4

Javascript (ES6) 324 312 309 Bytes

Saya yakin ini bisa sedikit 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'))}
  • menciptakan kanvas
  • membangun gambar di dalamnya
  • Buka url data untuk gambar di tab baru

Baris baru untuk keterbacaan:

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

Keluaran

JavaScript

Shaun H
sumber
Karena saya tidak menentukannya, Anda tidak perlu membuatnya berjalan otomatis.
Bálint
Juga, cukup masukkan variabel dummy daripada menggunakan paragraf kosong
Bálint
Paragraf kosong? Dimana?
Shaun H
f=()=>{Di sini, lakukan saja f=_=>, -1 byte, jangan gunakan itu, javascript diketik secara longgar
Bálint
Parameter Ah, meninggalkan parens saat ini lebih murah daripada menangani yang tidak dibagi rata oleh 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)

Tidak Disatukan:

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

Catatan: fmengembalikan kanvas.

Contoh menjalankan (mengasumsikan ada <body>untuk menambahkan):

document.body.appendChild(f())

Haruskah membuang gambar berikut ke halaman (diperbesar):

QuineImage

Dendrobium
sumber
Pixel terakhir benar-benar kosong, bisakah Anda membuatnya, jadi totalnya 71 piksel?
Bálint
@ Bálint Whoops, tidak melihat bagian piksel yang kosong. Cukup menarik, jika saya mencoba membuat gambar 71x1, yang meningkatkan jumlah byte saya menjadi 214 dan kebetulan, jumlah pixel menjadi 72, yaitu 9x8, yang pada gilirannya membawa jumlah byte kembali ke 213. Ini juga merusak perhitungan saluran alpha . Solusi terbersih saat ini yang memenuhi semua persyaratan adalah dengan menambahkan 3 karakter redundan ke solusi ...
Dendrobium
2

PowerShell v4, 64 byte

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

Itu mendapatkan konten dari nama file sendiri, melemparkan string sebagai array char, menambahkan beberapa header PPM dan mengatur konten ke a.ppm sebagai output. 64 byte membuatnya 11x2 piksel:

Sumber PowerShell dikodekan sebagai gambar

TessellatingHeckler
sumber
1

Node.js, 63 byte

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

Output gambar menjadi file bernama P6yang dalam format PPM (P6).

Berikut ini adalah membawakan PNG (7x3 piksel):

masukkan deskripsi gambar di sini

Mwr247
sumber
1

PHP, 226 byte

Golf

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

Versi tidak disatukan

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

Masukkan skrip ini ke file bernama 'p.php' dan jalankan. Anda memerlukan metode Anda sendiri untuk menjalankan skrip PHP, karena ini membaca dari file lokal.

Gambar output:

kode warna

Xanderhall
sumber
0

Java 511 karakter

Panjangnya solusi mengarah ke gambar yang lebih besar yang keren, karena gambar-gambar ini sangat bagus.

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

Perhatikan bahwa ada baris baru yang tidak terlihat! Bunyinya file sumber, yang harus "Q.java" dan membuat gambar "Q.png" yang terlihat seperti ini:

Gambar yang dihasilkan oleh kode

atau diskalakan 100x masukkan deskripsi gambar di sini

Frozn
sumber
0

APL (Dyalog) , 33 byte

Membutuhkan ⎕IO←0yang default pada banyak sistem. Selain itu, AutoFormat harus dimatikan untuk mempertahankan program persis seperti yang diberikan.

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

Hex B9 BA FD 4E 50 55 BB 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

Menciptakan P: P3 11 1 255 185 186 253 78 80 85 85 187 187 13 80 13 194 205 253 65 86 178 13 3 11 1 255 13 194 187 200 253 78 82 13 22 13
Yang Anda simpan dan jatuhkan di sini untuk melihat:gambar kode

⎕NR'f'N ested R epresentation program f

⊃⌽ pilih elemen (baris pertama yang dibalik) yang terakhir (lit)

'␍ɫ␉⍣', tambahkan empat karakter (filetype, lebar, tinggi, maks)

⎕AV⍳ temukan indeks yang sesuai dalam A tomic V ector (set karakter

 format sebagai teks

'P', tambahkan satu huruf

(... ) terapkan fungsi diam-diam berikut:

 ambil seluruh argumen [dan menjadi]

⎕NPUTAsli [file,] Masukkan [itu, dengan nama file yang terdiri dari]

 karakter pertama ("P")

Adm
sumber
Codepage apa yang diasumsikan ini?
Bálint
@ Bálint Lihat edit.
Adám
Kenapa gambar yang dihasilkan adalah 42 piksel, bukan 14? Apakah ini karena "byte" Anda sesuai dengan karakter multi-byte?
Suever
@Suever Diperbaiki. Terima kasih.
Adám
BTW, saya pikir, jika versi memiliki kompiler sebelum tantangan, maka itu adalah versi legal.
Bálint
-1

Python, 81 byte

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

Output dalam format PPM.

Seperti inilah gambarnya:

Gambar

Ditingkatkan:

Ditingkatkan

Loovjo
sumber
Saya tidak melihat Anda menggunakan kembaliq
Maltysen
Jika Anda menggunakan P6format, Anda tidak perlu mengonversi ke tata cara. Selain itu, untuk RGB 8-bit, 255sebaiknya digunakan 256.
Mego
Jika Anda hanya menggunakan qsekali, seperti yang tampaknya Anda lakukan, singkirkan tugas dan gantikan secara langsung - itu akan menghemat tiga byte.
Dana Gugatan Monica
Sepertinya Anda mencetak konten file, tetapi OP mengatakan Outputnya harus sebagai file terpisah .
Adám
Halo, @QPaysTaxes berkata print'P3\n9 3 256 '+' '.join(map(lambda x:str(ord(x)),open(__file__).read())). Ini -4 byte, tho!
Erik the Outgolfer