Zoom Sub-pixel

9

Tugas Anda adalah untuk mengambil gambar 24 BPP sRGB dan mengeluarkan gambar yang sama naik 3x menjadi subpiksel merah, hijau, dan biru. Gambar yang dihasilkan seluruhnya terbuat dari piksel hitam, merah, hijau, dan biru murni.

Setiap piksel dari gambar sumber, ketika diperbesar, menghasilkan pengaturan 9 sub-piksel yang dapat dihidupkan atau dimatikan (yaitu warna atau hitamnya masing-masing). Susunan khusus menggunakan tiga kolom merah, hijau, dan biru, dalam urutan itu, seperti:

Subpiksel RGB

(Perhatikan bahwa batas pada "piksel" ini hanya untuk demonstrasi.)

Karena masing-masing dari sembilan subpiksel hanya bisa hidup atau mati, Anda harus menghitung gambar input dan menggunakan pola subpiksel yang berbeda untuk mencapai 3 tingkat kecerahan.

Untuk setiap subpiksel dalam gambar:

  • Untuk tingkat warna 0-74, semua subpiksel harus berwarna hitam.
  • Untuk level warna 75-134, subpiksel tengah harus berwarna masing-masing dan dua lainnya harus hitam.
  • Untuk tingkat warna 135-179, subpiksel tengah harus hitam dan dua lainnya harus masing-masing warna
  • Untuk level warna 180-255, ketiga subpiksel harus berwarna masing-masing

Saya memilih rentang level ini karena itulah yang terlihat bagus

Terapkan transformasi ini ke setiap piksel dalam gambar dan hasilkan gambar yang di-subpiksel.

Contoh piksel tunggal

rgb (40, 130, 175) akan menghasilkan pola ini:

00B / 0G0 / 00B

rgb (160, 240, 100) akan menghasilkan pola ini:

RG0 / 0GB / RG0

Contoh Gambar Lengkap

Mona lisa Mona Lisa Subpixels

Malam berbintang Subpixels Malam Berbintang

Burung beo Subpixels Parrot

Gambar-gambar bersumber dari Wikipedia

Aturan dan catatan

  • Input dan output mungkin dalam format yang sesuai, apakah itu file gambar aktual atau (mungkin bersarang) daftar nilai-nilai RGB.
  • Anda dapat menganggap piksel berada dalam ruang warna sRGB dengan 24BPP.

Selamat bermain golf!

Beefster
sumber
2
Deskripsi awal terdengar seperti un-Bayering. Ternyata itu bukan, sebagian karena topeng 3x3 yang tidak konvensional tetapi terutama karena quantisation, tetapi IMO itu masih lebih dekat dengan un-Bayering daripada subpixel zooming (yang akan ditingkatkan dengan semacam deteksi tepi ke anti- alias).
Peter Taylor
terima kasih atas challenege yang menarik .... apakah ini sebenarnya digunakan untuk apa pun dalam kehidupan nyata?
don bright

Jawaban:

4

JavaScript (Node, Chrome, Firefox), 111 byte

Format I / O: matriks [R,G,B]nilai.

a=>[...a,...a,...a].map((r,y)=>r.flat().map((_,x)=>a[y/3|0][x/3|0].map(v=>x--%3|511+y%3%2*3104>>v/15&1?0:255)))

Cobalah online! (hanya satu piksel)

Bagaimana?

Semua nilai ambang adalah kelipatan dari 15. Alih-alih melakukan tes perbandingan eksplisit, itu sedikit lebih pendek untuk menguji bitmask di mana setiap bit mewakili interval 15 nilai (kecuali bit paling signifikan yang dipetakan ke nilai tunggal).

 bit | range   | top/bottom | middle
-----+---------+------------+--------
  0  |   0- 14 |     off    |   off
  1  |  15- 29 |     off    |   off
  2  |  30- 44 |     off    |   off
  3  |  45- 59 |     off    |   off
  4  |  60- 74 |     off    |   off
  5  |  75- 89 |     off    |    on
  6  |  90-104 |     off    |    on
  7  | 105-119 |     off    |    on
  8  | 120-134 |     off    |    on
  9  | 135-149 |      on    |   off
 10  | 150-164 |      on    |   off
 11  | 165-179 |      on    |   off
 12  | 180-194 |      on    |    on
 13  | 195-209 |      on    |    on
 14  | 210-224 |      on    |    on
 15  | 225-239 |      on    |    on
 16  | 240-254 |      on    |    on
 17  |   255   |      on    |    on

10

Kita mendapatkan:

  • 000000000111111111511
  • 0000001110000111113615

Berkomentar

a =>                      // a[] = input matrix
  [...a, ...a, ...a]      // create a new matrix with 3 times more rows
  .map((r, y) =>          // for each row r[] at position y:
    r.flat()              //   turn [[R,G,B],[R,G,B],...] into [R,G,B,R,G,B,...]
                          //   i.e. create a new list with 3 times more columns
    .map((_, x) =>        //   for each value at position x:
      a[y / 3 | 0]        //     get [R,G,B] from the original matrix
       [x / 3 | 0]        //     for the pixel at position (floor(x/3), floor(y/3))
      .map(v =>           //     for each component v:
        x-- % 3 |         //       1) yield a non-zero value if this is not the component
                          //          that we're interested in at this position
        511 +             //       2) use either 511 for top and bottom pixels
        y % 3 % 2 * 3104  //          or 3615 for the middle pixel (y mod 3 = 1)
        >> v / 15         //          divide v by 15
        & 1               //          and test the corresponding bit
        ?                 //       if either of the above tests is truthy:
          0               //         yield 0
        :                 //       else:
          255             //         yield 255
      )                   //     end of map() over RGB components
    )                     //   end of map() over columns
  )                       // end of map() over rows

Contoh

Cuplikan kode berikut memproses kepala Mona Lisa (64x64). Tidak berfungsi di Edge.

Arnauld
sumber
3

Jelly , 27 byte

<“⁷KṆ‘‘Ḅœ?Ɗo⁹’)×€"3⁼þ¤)ẎZ)Ẏ

[0,255][r, g, b]

Cobalah online! Contoh ini mengambil gambar dua kali dua di mana piksel kiri atas adalah contoh pertama piksel, piksel kanan atas adalah contoh kedua piksel, piksel kiri bawah adalah piksel hitam dan piksel kanan bawah adalah putih pixel.

Bagaimana?

<“⁷KṆ‘‘Ḅœ?Ɗo⁹’)×€"3⁼þ¤)ẎZ)Ẏ - Link: list of lists of lists of integers, I
                         )  - for each row, R, in I:
                      )     -   for each pixel, P, in R:
              )             -     for each integer, C, in P:
 “⁷KṆ‘                      -       list of code-page indices = [135,75,180]
<                           -       less than -> [C<135,C<75,C<180] 
          Ɗ                 -       last three links as a monad:
      ‘                     -         increment -> [1+(C<135),1+(C<75),1+(C<180)]
       Ḅ                    -         from binary -> 4*(1+(C<135))+2*(1+(C<75))+1+(C<180)
        œ?                  -         permutation at that index of [C<135,C<75,C<180]
                            -         when all permutations sorted lexicographically
                            -       ... a no-op for all but [0,0,1]->[0,1,0]
            ⁹               -       256
           o                -       logical OR  e.g. [0,1,0]->[256,1,256]
             ’              -       decrement               ->[255,0,255]
                     ¤      -     nilad followed by link(s) as a nilad:
                  3         -       three
                    þ       -       table with: (i.e. [1,2,3] . [1,2,3])
                   ⁼        -         equal?    -> [[1,0,0],[0,1,0],[0,0,1]]
                 "          -     zip with:
                €           -       for each:
               ×            -         multiply
                       Ẏ    -   tighten (reduce with concatenation)
                        Z   -   transpose
                          Ẏ - tighten
Jonathan Allan
sumber
Saya mencoba mencari tahu di mana ia mengkodekan [[1,0,0]. [0,1,0], [0,0,1]] dan saya bingung.
don bright
@donbright 3⁼þ¤melakukan produk luar [1,2,3]=[1,2,3]menghasilkan [[1=1,2=1,3=1],[2=1,2=2,2=3],[3=1,3=2,3=3]]yang [[1,0,0],[0,1,0],[0,0,1]].
Jonathan Allan
2

Bahasa Wolfram (Mathematica) , 186 byte

Input dan Output adalah daftar nilai RGB

(g=#;Flatten[(T=Transpose)@Flatten[T/@{{#,v={0,0,0},v},{v,#2,v},{v,v,#3}}&@@(If[(l=Max@#)<75,v,If[74<l<135,{0,l,0},If[134<l<179,{l,0,l},{l,l,l}]]]&/@#)&/@g[[#]],1]&/@Range[Length@g],1])&

Cobalah online!


Bahasa Wolfram (Mathematica), 243 byte

kode kedua ini adalah fungsi yang berfungsi sebagai input gambar dan menampilkan gambar
(saya tidak tahu mengapa orang bingung dalam komentar)

Jadi, jika Anda memberi makan gambar ini

masukkan deskripsi gambar di sini

ke dalam fungsi ini

(i=#;Image[Flatten[(T=Transpose)@Flatten[T/@{{#,v={0,0,0},v},{v,#2,v},{v,v,#3}}&@@(If[(l=Max@#)<75,v,If[74<l<135,{0,l,0},If[134<l<179,{l,0,l},{l,l,l}]]]&/@#)&/@ImageData[i,"Byte"][[#]],1]&/@Range[Last@ImageDimensions@i],1],ColorSpace->"RGB"])&


Anda akan mendapatkan output ini

masukkan deskripsi gambar di sini

J42161217
sumber
2
Bukankah ini akan dihitung sebagai input hardcoded?
attinat
"Input dan output mungkin dalam format yang sesuai, apakah itu file gambar aktual ...". Tidak, iini gambar.
J42161217
Saya setuju dengan @attinat, ini sepertinya hardcoding.
Jonathan Frech
Saya membuat beberapa perubahan dan saya berharap semuanya jelas sekarang.
J42161217
1

C # (Visual C # Interactive Compiler) , 157 byte

n=>{int i=0,j=n[0].Length;for(;;Write(z(0)+",0,0|0,"+z(1)+",0|0,0,"+z(2)+"\n|"[++i%j&1]));int z(int k)=>(((511^i/j%3%2*4064)>>n[i/j/3][i%j][k]/15)&1^1)*255;}

Mencetak RGB dari output. Output dipisahkan baris baru dan tidak selaras. Awalnya, saya menggunakan bit-mask dengan 1on dan 0off, tapi kemudian saya melihat jawaban Arnauld, dan saya menyadari menggunakan 0sebagai aktif dan tidak 1aktif dapat menghemat byte dalam nomor tersebut. TIO Link berisi "gambar" sampel 4 x 2 piksel.

Cobalah online!

Perwujudan Ketidaktahuan
sumber
0

APL + WIN, 102 byte

Anjuran untuk matriks 2d piksel sebagai bilangan bulat 24 bit seperti yang akan ditampilkan pada gambar

((⍴a)⍴,3 3⍴255*⍳3)×a←(3 1×⍴m)⍴∊⍉((1↓⍴m)/⍳↑⍴m)⊂n←(-+⌿n)⊖n←1 0↓0 75 135 180∘.≤,m←(1 3×⍴m)⍴,⍉(3⍴256)⊤,m←⎕

Cobalah online! Atas perkenan Dyalog Classic

Menghasilkan matriks 2d dari bilangan bulat 24 bit dari gambar yang diubah. Sebagian besar kode menangani format input dan output.

Contoh: Ambil gambar 2 x 2 yang terdiri dari piksel sampel

Memasukkan:

2654895 10547300
2654895 10547300

Keluaran:.

0     0 16581375 255 65025        0
0 65025        0   0 65025 16581375
0     0 16581375 255 65025        0
0     0 16581375 255 65025        0
0 65025        0   0 65025 16581375
0     0 16581375 255 65025        0
Graham
sumber
0

Karat - 281 byte

fn z(p:Vec<u8>,wh:[usize;2])->Vec<u8>{let mut o=vec![0;wh[0]*wh[1]*27];for m in 0..wh[0]{for n in 0..wh[1]{for i in 1..=3{for j in 0..3{o[m*9+n*wh[0]*27+j*wh[0]*9+i*2]=match p[18+m*3+n*wh[0]*3+3-i]{75..=134=>[0,1,0],135..=179=>[1,0,1],180..=255=>[1,1,1],_=>[0,0,0],}[j]*255;}}}}o}

Baris ini adalah fungsi yang memenuhi tantangan, namun inputnya sebenarnya adalah data dalam format file TGA seperti yang dijelaskan di paulbourke.net , bersama dengan lebar dan tinggi pra-parsing, dalam piksel, dari gambar. Ini mengembalikan data piksel untuk output, sebagai byte, dalam vektor 9 kali ukuran data piksel input.

use std::fs::File;use std::io::{Read,Write};fn main(){let mut p=vec![];let mut o=vec![0u8;18];File::open("i.tga").unwrap().read_to_end(&mut p).unwrap();let mut wh=[0;2];let h=|x|p[x] as usize;let g=|x|(3*x/256) as u8;for i in 0..2{wh[i]=h(12+i*2)+256*h(13+i*2);o[12+i*2]=g(wh[i]*256);o[13+i*2]=g(wh[i]);}let mut f=File::create("o.tga").unwrap();o[2]=2;o[16]=24;o.extend(z(p,wh));f.write(&o).unwrap();}

Baris kedua ini adalah fungsi utama () yang dapat mengubah file input bernama i.tga menjadi file output bernama o.tga, dengan memanggil fungsi z dari baris pertama, tanpa menggunakan perpustakaan eksternal apa pun. Ini menangani penguraian lebar / tinggi, membuat header untuk file output, dan membaca file + menulis. Itu akan menambah 402 byte jika tantangan diperlukan File I / O, dengan total 683. Ini berguna untuk pengujian.

jangan cerah
sumber