Zoom sous-pixel

9

Votre tâche consiste à prendre une image sRGB 24 BPP et à sortir la même image 3 fois en haut de l'échelle en sous-pixels rouges, verts et bleus. L'image résultante sera entièrement composée de pixels noirs, rouges, verts et bleus purs.

Chaque pixel de l'image source, lorsqu'il est agrandi, produit un arrangement de 9 sous-pixels qui peuvent être activés ou désactivés (c'est-à-dire leur couleur respective ou le noir). L'arrangement spécifique utilise trois colonnes de rouge, vert et bleu, dans cet ordre, comme suit:

Sous-pixels RVB

(Notez que les bordures de ces "pixels" sont uniquement à des fins de démonstration.)

Étant donné que chacun des neuf sous-pixels ne peut être activé ou désactivé, vous devrez quantifier l'image d'entrée et utiliser différents modèles de sous-pixels pour obtenir 3 niveaux de luminosité.

Pour chaque sous-pixel de l'image:

  • Pour les niveaux de couleur 0 à 74, tous les sous-pixels doivent être noirs.
  • Pour les niveaux de couleur 75-134, le sous-pixel du milieu doit être la couleur respective et les deux autres doivent être noirs.
  • Pour les niveaux de couleur 135-179, le sous-pixel du milieu doit être noir et les deux autres doivent être la couleur respective
  • Pour les niveaux de couleur 180-255, les trois sous-pixels doivent être leur couleur respective

J'ai choisi ces gammes de niveaux parce que c'est ce qui se passait bien

Appliquez cette transformation à chaque pixel de l'image et sortez l'image agrandie en sous-pixels.

Exemples à pixel unique

rgb (40, 130, 175) produira ce modèle:

00B / 0G0 / 00B

rgb (160, 240, 100) produira ce modèle:

RG0 / 0GB / RG0

Exemples d'images complètes

Mona Lisa Mona Lisa Subpixels

Nuit étoilée Sous-pixels de la nuit étoilée

Perroquet Parrot Subpixels

Images provenant de Wikipedia

Règles et notes

  • L'entrée et la sortie peuvent être dans n'importe quel format pratique, qu'il s'agisse de fichiers d'image réels ou de listes (éventuellement imbriquées) de valeurs RVB.
  • Vous pouvez supposer que les pixels sont dans l'espace colorimétrique sRGB avec 24BPP.

Bon golf!

Beefster
la source
2
La description initiale ressemble à un non-Bayering. Il s'avère que ce n'est pas le cas, en partie à cause du masque 3x3 non conventionnel, mais principalement à cause de la quantification, mais l'OMI est toujours plus proche de la non-Bayering que du zoom sous-pixel (qui serait une mise à l'échelle avec une sorte de détection de bord vers une alias).
Peter Taylor
merci pour un défi intéressant .... est-ce réellement utilisé pour quelque chose dans la vraie vie?
Don Bright

Réponses:

4

JavaScript (Node, Chrome, Firefox), 111 octets

Format d'E / S: matrice de [R,G,B]valeurs.

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

Essayez-le en ligne! (juste un seul pixel)

Comment?

Toutes les valeurs de seuil sont des multiples de 15. Au lieu de faire des tests de comparaison explicites, il est un peu plus court de tester un masque de bits où chaque bit représente un intervalle de 15 valeurs (sauf le bit le plus significatif qui est mappé sur une seule valeur).

 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

On a:

  • 000000000111111111511
  • 0000001110000111113615

Commenté

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

Exemple

L'extrait de code suivant traite la tête de Mona Lisa (64x64). Ne fonctionne pas sur Edge.

Arnauld
la source
3

Gelée , 27 octets

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

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

Essayez-le en ligne! Cet exemple prend une image deux par deux où le pixel supérieur gauche est le premier exemple de pixel, le pixel supérieur droit est le deuxième exemple de pixel, le pixel inférieur gauche est un pixel noir et le pixel inférieur droit est un blanc pixel.

Comment?

<“⁷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
la source
im essayant de comprendre où il code [[1,0,0]. [0,1,0], [0,0,1]] et je suis déconcerté.
Don Bright
@donbright 3⁼þ¤réalise un produit extérieur de [1,2,3]=[1,2,3]rendement [[1=1,2=1,3=1],[2=1,2=2,2=3],[3=1,3=2,3=3]]qui est [[1,0,0],[0,1,0],[0,0,1]].
Jonathan Allan
2

Wolfram Language (Mathematica) , 186 octets

L'entrée et la sortie sont des listes de valeurs RVB

(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])&

Essayez-le en ligne!


Wolfram Language (Mathematica), 243 octets

ce deuxième code est une fonction qui prend en entrée une image et sort une image
(je ne sais pas pourquoi les gens étaient confus dans les commentaires)

Donc, si vous nourrissez cet img

entrez la description de l'image ici

dans cette fonction

(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"])&


vous obtiendrez cette sortie

entrez la description de l'image ici

J42161217
la source
2
Cela ne serait-il pas considéré comme une entrée codée en dur?
attinat
"L'entrée et la sortie peuvent être dans n'importe quel format pratique, qu'il s'agisse de fichiers d'image réels ...". Non, ic'est une image.
J42161217
Je serais d'accord avec @attinat, cela ressemble à du codage en dur.
Jonathan Frech
J'ai fait quelques changements et j'espère que tout est clair maintenant.
J42161217
1

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

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

Imprime le RVB de la sortie. La sortie est séparée par des sauts de ligne et non alignée. À l'origine, j'utilisais un masque de bits pour 1être activé et 0désactivé, mais j'ai ensuite vu la réponse d'Arnauld, et je me suis rendu compte qu'utiliser 0comme activé et 1désactivé pouvait économiser des octets dans le nombre. Le lien TIO contient une "image" d'échantillon de 4 x 2 pixels.

Essayez-le en ligne!

Incarnation de l'ignorance
la source
0

APL + WIN, 102 octets

Demande une matrice 2d de pixels sous forme d'entiers 24 bits tels qu'ils apparaissent dans l'image

((⍴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←⎕

Essayez-le en ligne! Gracieuseté de Dyalog Classic

Produit une matrice 2d d'entiers 24 bits de l'image transformée. La plupart du code gère la mise en forme de l'entrée et de la sortie.

Exemple: prendre une image 2 x 2 composée des pixels échantillons

Contribution:

2654895 10547300
2654895 10547300

Production:.

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
la source
0

Rouille - 281 octets

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}

Cette ligne est une fonction qui relève le défi, mais son entrée est en fait des données au format de fichier TGA comme décrit sur paulbourke.net , ainsi que la largeur et la hauteur pré-analysées, en pixels, de l'image. Il renvoie des données de pixels pour la sortie, sous forme d'octets, dans un vecteur 9 fois la taille des données de pixels d'entrée.

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

Cette deuxième ligne est une fonction main () qui peut transformer un fichier d'entrée nommé i.tga en un fichier de sortie nommé o.tga, en appelant la fonction z à partir de la première ligne, sans utiliser de bibliothèques externes. Il gère l'analyse de largeur / hauteur, la création d'un en-tête pour le fichier de sortie et la lecture + écriture du fichier. Il ajouterait 402 octets si le défi nécessitait des E / S de fichiers, pour un total de 683. Il est utile pour les tests.

Don Bright
la source