캔버스로 캐릭터를 픽셀화하고 생성 예술을 그립니다!

, 저는 p5.js 으로 제너레이티브 아트를 배우고 있습니다.

이 글에서는 학습 과정을 통해 만든 "String Pixelator"라는 도구를 소개합니다.
  • GitHub: https://github.com/ohbarye/string-pixelater
  • npm: https://www.npmjs.com/package/string-pixelater

  • 문자열 픽셀레이터란?





    이것은 모든 문자를 픽셀화하는 간단한 도구입니다. pixelate는 여러 목적으로 테이블 형식 데이터를 처리할 수 있도록 "문자를 2차원 배열로 변환"하는 것을 의미합니다. 나는 실제로 생성 예술을 그리기 위해 이것과 p5.js을 구성합니다.

    그것이 어떻게 작동하는지 파헤쳐 봅시다... 하지만 지금까지 단 하나의 API만 가지고 있습니다!

    > StringPixelater.pixelate('hello', {fontSize: 24})
    
    [
      [0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
      [0,0,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0],
      [0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0],
      [0,0,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0],
      [0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,0,0],
      [0,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0]
    ]
    


    위의 "hello"를 막연하게 볼 수 있습니까?

    어떻게 작동합니까?



    즉, <canvas> 요소를 임시 캔버스로 사용하여 문자를 렌더링합니다. 그런 다음 래스터화된 이미지 데이터를 추출하고 구문 분석합니다. 필수 코드는 다음과 같습니다.

    const canvas = <HTMLCanvasElement> document.createElement('canvas');
    const context = <CanvasRenderingContext2D> this.canvas.getContext('2d');
    context.fillText("hello", 0, 0);
    
    let table = new Array(canvas.height);
    
    const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
    
    for (let row = 0; row < canvas.height; row++){
      table[row] = new Array(canvas.width);
    
      for (let col = 0; col < canvas.width; col++){
        const alpha = imageData.data[(canvas.width * row + col) * 4 + 3];
        if (alpha >= 64) {
          table[row][col] = 1;
        } else {
          table[row][col] = 0;
        }
      }
    }
    


    용법



    픽셀화하려는 문자열을 사용하여 StringPixelater.pixelate 메서드를 설치하고 호출하기만 하면 됩니다.

    $ npm install --save string-pixelater
    or
    $ yarn add string-pixelater
    


    ES 모듈로 사용하거나 <script> 태그를 통해 로드할 수 있습니다.

    import StringPixelater from 'string-pixelater';
    
    const table = StringPixelater.pixelate('Hello, world');
    



    <script type="text/javascript" src="path/to/dist/js/string-pixelater.js"></script>
    <script type="text/javascript">
      var table = StringPixelater.pixelate('Hello, world');
    </script>
    


    바꾸어 놓다



    저처럼 p5.js를 쓰시는 분들은 transpose 옵션이 반전축이 있어서 상당히 편리하고,

    > StringPixelater.pixelate('B', {fontSize: 24, transpose: false})
    [
      [0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0],
      [0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0],
      [0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
      [0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0],
      [0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0],
      [0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0],
      [0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
      [0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0]
    ]
    
    > StringPixelater.pixelate('B', {fontSize: 24, transpose: true})
    [
      [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
      [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
      [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
      [1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1],
      [1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1],
      [1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1],
      [1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1],
      [1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1],
      [1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1],
      [1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1],
      [1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1],
      [1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1],
      [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
      [0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0],
      [0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0],
      [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
    ]
    


    후자는 단순하고 직관적인 루프로 렌더링될 때 올바르게 보입니다.

    // Note: This is just pseudo code!
    function draw() {
      const imageData = StringPixelater.pixelate('B', {fontSize: 24, transpose: true})
      const pixelSize = 10;
    
      imageData.forEach(function(row, i) {
        row.forEach(function(cell, j) {
          if (cell === 1) {
            ellipse(i * pixelSize, j * pixelSize, pixelSize, pixelSize);
          }
        })
      })
    }
    


    결과는 아래와 같습니다.



    String Pixelator를 사용한 작품


    StringPixelater.pixelate('hello')와 함께:


    StringPixelater.pixelate('🐈')와 같이 픽셀화된 이모지를 얻을 수 있습니다.




    누군가 이 글을 통해 제너레이티브 아트나 string-pixelater에 관심을 가져주신다면 기쁘겠습니다. :)

    좋은 웹페이지 즐겨찾기