[C#] 프로그래밍에 필요한 pixel 이미지 만들기 그리고 스트라이프 이미지 만들기


Development note/C#  2021. 1. 29. 11:09

안녕하세요. 명월입니다.


이 글은 C#에서 프로그래밍에 필요한 pixel 이미지(도트 이미지) 만들기 그리고 스트라이프 이미지 만들기에 대한 글입니다.


예전에는 윈도우 프로그래밍을 하면서 버튼이던가 게임이라고 하면 그래픽등을 일일히 개발자가 도트를 찍어서 작업했던게 생각납니다. 최근에는 워낙 그래픽 퀄리티가 좋다보니 개발자가 디자인해서 만들기는 힘들고 디자이너들이 있어서 작업을 해서 프로그램에 입혀서 작업합니다.

그래도 공부하거나 옛날 갬성(?)의 분위기로 프로그램을 만들때 도트이미지를 일부러 사용하는 것 같더라구요. 도트 아트 혹은 픽셀 아트라고 해서 도트식으로 작성하는 작품도 많이 있습니다.


이것도 디자인 작업이라고해서 많은 분들이 포토샵이나 일러스터를 사용하는 분도 있으신것 같은데.. 개발자가 프로그램 리소스용으로 만들기 위해서 포토샵이나 일러스터까지 구입하는 건 조금 오바인듯 싶고...

이제는 무료가 된.. 개인적으로 최고라고 생각하는 개발 툴(IDE)의 Visual studio에서 이 도트이미지를 작성하는 것을 지원합니다. 그냥 Visual studio에서 작업하면 쉽게 만들 수 있습니다.


그냥 프로젝트를 하나 생성하고 프로젝트에서 Bit이미지를 추가하면 Pixel 이미지 작업 툴이 나옵니다.

이미지를 생성하게 되면 아래와 같이 그림판 비슷한 도트 작업 툴이 나오게 됩니다.

먼저 작업 영역을 설정하는 데 왼쪽 위의 사각 마크를 클릭하고 Ctrl + A로 전체 범위를 선택하고 Enter를 누르면 작업을 할 수 있습니다.

그리고 도트의 눈금도 필요한데 중간에 테이블 마크를 클릭하게 되면 눈금 표시가 나옵니다.

오른쪽 아래에 보면 이미지의 크기와 색 포멧을 설정할 수 있습니다.

보통 그 이상인 128이나 256, 1024까지 만들 수 있는데.. 그럼 아마 128 * 128 = 16384 도트를 찍어야 하기 때문에 꽤 힘들 수 있습니다. 그리고 그 이하인 32는 도트 이미지이지만 도트가 너무 심하게 표현되니 제가 보기엔 64가 적당한 듯 싶습니다.

Format은 색 종류인데, 흑백 스타일이 아닌 이상 그냥 32bpp BGR(약 1600만 컬러)를 사용합니다.


저는 예제를 위해서 itch사이트에서 무료 이미지를 구했습니다.

이 도트 이미지를 한장한장 도트로 만들어서 두타입이 총 14장, 10장이 만들어 졌습니다

이제 이것을 Graphic 객체를 사용하여 화면에 표시할 수 있습니다.

문제는 파일이 여러개이다보니 IO 리소스(resource)가 많이 사용하게 되겠네요. IO 리소스는 일단 하드디스크를 읽어오는 작업이기 때문에 매우 느립니다. 여기서야 총 24장이니 크게 차이가 나지 않겠지만 게임같이 많은 양의 이미지를 사용한다고 하면 이 IO도 무시 못할 성능 저하로 이어집니다.

그러면 어떻게 하는게 좋을까?

스프라이프 이미지(여러개의 이미지를 하나로 합치는 작업)를 작성해서 IO는 하나로 읽고 프로그램에서 이미지의 좌표로 표시(?)하는 방법으로 하는 것이 IO 자원을 아낄 수 있습니다.

그럼 이 여러 이미지를 하나로 합쳐야 겠네요.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;

namespace Example
{
  class Program
  {
    // 스트라이브 작성
    static void CreateStripeImage(string path, string output)
    {
      // 이미지 폴더
      var info = new DirectoryInfo(path);
      // 이미지 리스트 작성
      var images = new List<Image>();
      // 폴더에서 이미지 가져오기.. 파일명 순으로 정렬, 즉 0.bmp -> 1.bmp -> 2.bmp ...
      foreach (var file in info.GetFiles().OrderBy(x => int.Parse(x.Name.Replace(x.Extension, ""))))
      {
        // 이미지 리스트에 이미지를 읽어와서 저장
        images.Add(Bitmap.FromFile(file.FullName));
      }
      // 메모리 이미지 크기는 세로 64, 가로 64 * 이미지 개수
      using (var b = new Bitmap(64 * images.Count, 64))
      {
        // Graphic 객체 읽어오기
        using (var g = Graphics.FromImage(b))
        {
          // 바탕색은 하얀색 (작성후 바탕생은 투명하게 교체할 예정.. 그런데 이미지에 흰색이 있으면 녹생을 해도..일명 그로마키 색)
          g.Clear(Color.White);
          // index
          int index = 0;
          // 리스트의 이미지를 버퍼에 그린다.
          foreach (var image in images)
          {
            // 위치는 가로로 index별로 64픽셀만큼 이동한다.
            g.DrawImage(image, new Rectangle(new Point(64 * index++, 0), new Size(64, 64)), 0, 0, 64, 64, GraphicsUnit.Pixel);
          }
          // 그로마키 색(흰색)을 투명하게 바꾼다.
          b.MakeTransparent(Color.White);
          // 무손실 포멧으로 출력
          b.Save(output, ImageFormat.Png);
        }
      }
    }
    static void Main(string[] args)
    {
      // AppDomain.CurrentDomain.BaseDirectory는 bin/debug 폴더이기 때문에 프로젝트 폴더로 이동후 a폴더
      CreateStripeImage(AppDomain.CurrentDomain.BaseDirectory + @"../../a", @"d:\work\output1.png");
      CreateStripeImage(AppDomain.CurrentDomain.BaseDirectory + @"../../b", @"d:\work\output2.png");

      // 콘솔 출력
      Console.WriteLine("\rPress any key...");
      Console.ReadKey();
    }
  }
}

작성되었습니다.

이제 이 스트라이프 이미지를 이용해서 Form 화면에 구현하면 됩니다.

링크 - [C#] GDI의 Graphic 객체 사용법과 더블 버퍼링 구현하는 방법


여기까지 C#에서 프로그래밍에 필요한 pixel 이미지 만들기 그리고 스트라이프 이미지 만들기에 대한 글이었습니다.


궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.