david's daily developer note

C#, 이미지 작업. 본문

[Develop] Language/C#

C#, 이미지 작업.

mouse-david 2010. 12. 8. 17:17
728x90

C#에서 이미지 작업을 위한 기본적인 소스를 작성해본다.

1. 화면에 뿌려질 바탕 이미지를 초기화 한다. 뿌려질 폼의 크기와 같은 Bitmap 클레스를 만들고, Bitmap 클레스에서 Graphics을 얻어온다. 아래 소스의 grBm 은 바탕 이미지의 Graphics이 되고, 오픈한 이미지나 작업한 이미지를 뿌리게 된다.

Bitmap drawBitmap = new Bitmap(ClientSize.Width, ClientSize.Height);
    Graphics grBm = Graphics.FromImage(drawBitmap);
    grBm.Clear(BackColor);


2. 앞에서 이미지를 뿌리기 위해서 초기화한 Graphics를 뿌려주는 이벤트를 추가하자. 이벤트는 폼의 변화가 발생하면 발생해야 함으로, Window Form의 Paint이벤트를 추가한다. 다음의 함수는 발생되는 Draw 이벤트에서 그래픽을 얻어오고, 해당 그래픽을 이용해서 앞서 만든 바탕 이미지를 뿌린다.

private void Form1_Paint(object sender, PaintEventArgs e)
    {
        Graphics gr = e.Graphics;
        gr.DrawImage(drawBitmap, 0, 0);
    }


3. 1번 과정에서 이미지를 그릴, 바탕 이미지를 만들었고, 바탕 이미지가 Draw될 수 있는 이벤트를 추가하였다. 다음은 실제 출력할 이미지를 불러와서 출력하자.

Image image = Image.FromFile(filePath); // image
grBm.DrawImage(image, 0, 0, image.Width, image.Height);


기본적인 이미지 불러오기와 뿌리는 방법을 알았다. 추가로, 픽셀 단위 영상 처리를 위해서 불러온 이미지를 그레이스케일(Gray-Scale)로 변환하고, 다시 출력가능한 이미지로 복귀하는 방법을 알아보자. 

4. 그레이스케일(Gray-Scale)로 변환
아래 함수의 내용은, Bitmap 을 Gray이미지로 바꾸는 과정이다. 이미지의 각 픽셀 단위 연산을 위해서는 Image 클레스를 아래와 같이 Bitmap 클레스로 변환하여 처리한다. Bitmap의 각 픽셀은 X,Y축 정보로 접근 가능하며, GetPixel 함수로 읽어올 수 있다. 이 때, 각 한 픽셀단위를 처리하는 클레스는 Color이다. 즉, 아래의 함수는 Bitmap의 각 픽셀의 R,G,B값을 섞어서 0~255값 사이의 Gray값으로 변환한다.

Bitmap bitmap = new Bitmap(image);

int[,] GrayScale(Bitmap tempImage)

int x, y, brightness;
Color color;
int[,] grayArray = new int[tempImage.Height, tempImage.Width];

for (y = 0; y < tempImage.Height; y++) {
    for (x = 0; x < tempImage.Width; x++) {
        color = tempImage.GetPixel(x, y);
        brightness = (int)(0.299 * color.R + 0.578 * color.G + 0.114 * color.B);
        grayArray[y, x] = brightness;
    }
}
return grayArray;


5. 생성한 Gray이미지를 출력가능한 Bitmap으로 변환. 이 과정은 앞의 4번 과정의 반대로, 2차원 int 배열로 저장된 gray 이미지의 각 픽셀을 Color 클레스로 생성하고, 새로운 Bitmap에 생성된 Color클레스를 입력하는 방식이다. 최종 출력되는 이미지는 그레이 스케일된 이미지이다.

int x, y;
Color color;
Bitmap gBitmap = new Bitmap(Width, Height);
for (y = 0; y < Height; y++) {
    for (x = 0; x < Width; x++) {
        color = Color.FromArgb(resultArray[y, x], resultArray[y, x], resultArray[y, x]);
        gBitmap.SetPixel(x, y, color);
    }
}

6. 4,5번 과정을 응용해서, R,G,B값을 잃어버리지 않고도 영상 처리할 수 있으며, 픽셀 단위 처리하는 왠만한 영상 처리를 할 수 있다.

728x90