서브 픽셀 줌


9

당신의 임무는 24 BPP sRGB 이미지를 가져 와서 3 배 업 스케일 된 동일한 이미지를 빨강, 녹색 및 파랑 서브 픽셀로 출력하는 것입니다. 결과 이미지는 완전히 순수한 검은 색, 빨간색, 녹색 및 파란색 픽셀로 만들어집니다.

소스 이미지의 각 픽셀은 확대 / 축소 될 때 켜거나 끌 수있는 9 개의 하위 픽셀 배열을 만듭니다 (예 : 해당 색상 또는 검은 색). 특정 배열은 다음과 같이 빨간색, 녹색 및 파란색의 세 열을 순서대로 사용합니다.

RGB 서브 픽셀

(이 "픽셀"의 테두리는 데모 용입니다.)

9 개의 서브 픽셀은 각각 켜거나 끌 수 있기 때문에 입력 이미지를 양자화하고 다른 서브 픽셀 패턴을 사용하여 3 단계의 밝기를 달성해야합니다.

이미지의 각 하위 픽셀에 대해 :

  • 색상 수준이 0-74 인 경우 모든 하위 픽셀이 검은 색이어야합니다.
  • 색상 수준 75-134의 경우 중간 하위 픽셀은 각각의 색상이어야하고 나머지 2 개는 검은 색이어야합니다.
  • 색상 수준 135-179의 경우 중간 하위 픽셀은 검은 색이어야하고 나머지 2 개는 각각의 색상이어야합니다
  • 색상 수준이 180-255 인 경우 세 개의 하위 픽셀이 모두 각각의 색상이어야합니다

나는 이러한 레벨 범위를 선택했습니다.

이 변환을 이미지의 모든 픽셀에 적용하고 서브 픽셀 업 스케일 된 이미지를 출력하십시오.

단일 픽셀 예

rgb (40, 130, 175)는 다음 패턴을 생성합니다.

00B / 0G0 / 00B

rgb (160, 240, 100)는 다음 패턴을 생성합니다.

RG0 / 0GB / RG0

전체 이미지 예

모나리자 모나리자 서브 픽셀

별이 빛나는 밤 별이 빛나는 밤 서브 픽셀

앵무새 앵무새 서브 픽셀

Wikipedia에서 제공 한 이미지

규칙과 메모

  • 입력 및 출력은 실제 이미지 파일이든 (또는 중첩 된) RGB 값 목록이든 편리한 형식 일 수 있습니다.
  • 픽셀이 24BPP 인 sRGB 색상 공간에 있다고 가정 할 수 있습니다.

행복한 골프!


2
초기 설명은 바 이어링 해제처럼 들립니다. 그것은 부분적으로 기존의 3x3 마스크 때문이 아니라 주로 양자화 때문인 것으로 밝혀졌습니다. 그러나 IMO는 서브 픽셀 줌보다 언베 이어링에 더 가깝습니다. 별명).
피터 테일러

흥미로운 도전에 감사드립니다 .... 이것은 실제 생활에서 실제로 사용됩니까?
밝게 돈

답변:


4

자바 스크립트 (노드, Chrome, Firefox), 111 바이트

I / O 형식 : [R,G,B]값의 행렬 .

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

온라인으로 사용해보십시오! (단일 픽셀)

어떻게?

모든 임계 값은 15의 배수입니다. 명시적인 비교 테스트를 수행하는 대신 각 비트가 15 개의 값 간격을 나타내는 비트 마스크를 테스트하는 것이 약간 짧습니다 (단일 값에 매핑되는 최상위 비트는 제외).

 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 선행 0의 수를 최대화하기 위해.

우리는 얻는다 :

  • 000000000111111111 상단 및 하단 픽셀 용 (511 십진수로)
  • 000000111000011111 가운데 픽셀 (3615 십진수로)

댓글

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

다음 코드 스 니펫은 Mona Lisa (64x64)의 헤드를 처리합니다. Edge에서는 작동하지 않습니다.


3

젤리 , 27 바이트

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

목록 (픽셀)의 목록 (행) 목록 (그림)을 허용하는 모나드 링크 각 픽셀은 3 개의 정수[0,255], [r, g, b]결과는 같은 형식으로 나타납니다.

온라인으로 사용해보십시오! 이 예는 왼쪽 상단 픽셀이 첫 번째 예제 픽셀이고 오른쪽 상단 픽셀이 두 번째 예제 픽셀, 왼쪽 하단 픽셀이 검은 색 픽셀, 오른쪽 하단 픽셀이 흰색 인 2x2 이미지를 가져옵니다. 픽셀.

어떻게?

<“⁷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

im이 [[1,0,0]. [0,1,0], [0,0,1]]을 인코딩하는 위치를 알아 내려고 노력하고 있으며 당황합니다.
밝게 돈을

@donbright 3⁼þ¤수행의 외적 [1,2,3]=[1,2,3]수득 [[1=1,2=1,3=1],[2=1,2=2,2=3],[3=1,3=2,3=3]]이다 [[1,0,0],[0,1,0],[0,0,1]].
Jonathan Allan

2

Wolfram Language (Mathematica) 186 바이트

입력 및 출력은 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])&

온라인으로 사용해보십시오!


Wolfram Language (Mathematica), 243 바이트

이 두 번째 코드는입니다 기능 입력으로 취 이미지 와 출력 이미지를
(사람들이 코멘트에 혼란 이유를 모르겠어요)

이 img를 먹이면

여기에 이미지 설명을 입력하십시오

이 기능으로

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


당신은이 출력을 얻을 것이다

여기에 이미지 설명을 입력하십시오


2
이것은 하드 코딩 된 입력으로 간주되지 않습니까?
attinat

"실제 이미지 파일인지 여부에 상관없이 입력 및 출력이 편리한 형식 일 수 있습니다." 아니요, i이미지입니다.
J42161217

@attinat에 동의합니다. 하드 코딩처럼 보입니다.
Jonathan Frech

나는 약간의 변경을했고 지금 모든 것이 명확 해지기를 바랍니다.
J42161217

1

C # (Visual C # 대화식 컴파일러) 157 바이트

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

출력의 RGB를 인쇄합니다. 출력은 줄 바꿈으로 구분되고 정렬되지 않습니다. 원래, 나는 1켜져 있고 0꺼져 있는 비트 마스크를 사용 했지만 Arnauld의 대답을 보았고 0on과 1off를 사용하면 바이트 수를 절약 할 수 있음을 깨달았습니다 . TIO 링크는 4 x 2 픽셀 샘플 "이미지"를 포함합니다.

온라인으로 사용해보십시오!


0

APL + WIN, 102 바이트

이미지에 나타나는 24 비트 정수로 픽셀의 2 차원 매트릭스를 프롬프트합니다.

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

온라인으로 사용해보십시오! Dyalog Classic 제공

변환 된 이미지의 24 비트 정수로 구성된 2 차원 행렬을 출력합니다. 대부분의 코드는 입력 및 출력 형식을 처리합니다.

예 : 샘플 픽셀로 구성된 2 x 2 이미지 촬영

입력:

2654895 10547300
2654895 10547300

산출:.

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

0

녹-281 바이트

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}

이 라인은 문제를 해결하는 기능이지만, 실제로 입력되는 이미지는 paulbourke.net에 설명 된대로 TGA 파일 형식의 데이터이며 이미지의 사전 파싱 된 너비와 높이 (픽셀)입니다. 입력 픽셀 데이터 크기의 9 배인 벡터로 출력 픽셀 데이터를 바이트 단위로 반환합니다.

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

이 두 번째 행은 외부 라이브러리를 사용하지 않고 첫 번째 행에서 함수 z를 호출하여 i.tga라는 입력 파일을 o.tga라는 출력 파일로 변환 할 수있는 main () 함수입니다. 너비 / 높이 구문 분석, 출력 파일의 헤더 작성 및 파일 읽기 + 쓰기를 처리합니다. 챌린지에 파일 I / O가 필요한 경우 총 683 개의 402 바이트를 추가합니다. 테스트에 유용합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.