달나라 노트

C# : Bitmap, GetPixel, ToArgb, FromArgb, SetPixel (이미지 다루기, 색상 다루기, ARGB 변환, Color 변환) 본문

C#/C#

C# : Bitmap, GetPixel, ToArgb, FromArgb, SetPixel (이미지 다루기, 색상 다루기, ARGB 변환, Color 변환)

CosmosProject 2022. 4. 7. 19:12
728x90
반응형

 

 

 

C#에서 이미지와 색상을 다룰 때 사용되는 method들을 알아봅시다.

 

일단 이 예시에서는 이미지가 필요합니다.

제가 그림판으로 그린 위 이미지를 아래의 경로에 미리 만들어둔 채로 예시를 진행할 것입니다.

C:\Users\Public\arrow.png

 

 

또한 여기서는 ARGB 색상에 대한 32비트 2진수 체계를 다룰 것입니다.

만약 이것에 대해 알고있지 않다면 아래 링크를 참고해서 먼저 ARGB 32비트 2진수 표현 체계를 알면 이 내용에서 다룰 method들의 이해가 더 쉬워질 것입니다.

https://cosmosproject.tistory.com/570

 

C# : &, |, ^, ~ (비트 논리곱, 비트 논리합, 비트 상호배제, 비트 부정)

& = 비트 논리곱 | = 비트 논리합 ^ = 비트 상호배제 ~ = 비트 부정 위 4개의 연산자는 모두 2진수 상태에서의 연산을 합니다. 인자로 받은 10진수를 2진수로 변경해서 연산한 후 그 결과를 다시 10진

cosmosproject.tistory.com

 

 

 

 

 

 

1. Bitmap

Bitmap class는 어떤 이미지를 픽셀단위로 읽어옵니다.

이미지에 존재하는 픽셀 하나하나의 정보를 일일이 읽어서 Bitmap 객체를 생성합니다.

 

using System;
using System.Drawing;

class MyProgram
{
    public static void Main()
    {
        Bitmap bm_img = new Bitmap("C:\\Users\\Public\\arrow.png");
    }
}

위처럼 Bitmap class의 인자로서 이미지의 경로를 적어주면 됩니다.

 

 

 

 

 

2. GetPixel(x, y)

GetPixel method는 Bitmap 객체에서 특정 위치(x, y)에 있는 픽셀의 정보를 얻어와서 그 픽셀에 대한 Color 객체를 생성합니다.

이미지의 왼쪽 상단이 0, 0이고 오른쪽으로 갈수록 x좌표가 1씩 늘어납니다. 그리고 아래쪽으로 갈수록 y좌표가 1씩 증가합니다.

 

using System;
using System.Drawing;

class MyProgram
{
    public static void Main()
    {
        Bitmap bm_img = new Bitmap("C:\\Users\\Public\\arrow.png");

        Color c = bm_img.GetPixel(0, 0);
        Console.WriteLine(c);
    }
}


-- Result
Color [A=255, R=153, G=217, B=234]

GetPixel로 Bitmap 객체의 (0, 0) 위치에 있는 픽셀 정보를 불러온 결과입니다.

픽셀의 정보는 ARGB 체계로 이뤄져있기에 A, R, G, B에 대한 각각의 값이 출력되는 것을 볼 수 있습니다.

 

 

 

 

 

 

3. ToArgb()

ToArgb() method는 GetPixcel로 얻은 Color 객체를 정수 ARGB 값으로 변경합니다.

 

using System;
using System.Drawing;

class MyProgram
{
    public static void Main()
    {
        Bitmap bm_img = new Bitmap("C:\\Users\\Public\\arrow.png");

        Color c = bm_img.GetPixel(0, 0);
        Console.WriteLine(c);

        int argb = c.ToArgb();
        Console.WriteLine(argb);
        Console.WriteLine(Convert.ToString(argb, 2));
    }
}


-- Result
Color [A=255, R=153, G=217, B=234]
-6694422
11111111100110011101100111101010

위 코드를 보면 ToArgb() method로 Color 객체인 c를 ARGB 정수값으로 변경하고 있습니다.

그 결과를 보면 -6694422 로 나옵니다. 사실 이 숫자자체는 크게 의미가 없고 이 숫자를 2진수로 바꿨을 때 의미가 있습니다.

 

2진수로 바꾼 결과를 보면 아래와 같습니다.

11111111100110011101100111101010

 

총 32자리의 2진수이며 8자리씩 나뉘어서 ARGB의 각 요소를 의미합니다.

11111111 10011001 11011001 11101010

11111111 -> 투명도(A)를 의미

10011001 -> 빨강(R)을 의미

11011001 -> 초록(G)을 의미

11101010 -> 파랑(B)을 의미

 

 

 

 

4. FromArgb()

FromArgb() method는 32비트(32 자리수)의 2진수로 된 ARGB 값을 Color 객체로 만들어줍니다.

단순히 32비트의 2진수 ARGB 값은 제대로 컴퓨터에 적용시킬 수 없습니다.

따라서 FromArgb() method를 이용해서 Color객체로 만들어준 후에 실제 이미지의 색상을 바꾸는 등의 작업을 할 수 있습니다.

 

using System;
using System.Drawing;

class MyProgram
{
    public static void Main()
    {
        int new_a = 255;
        int new_r = 255;
        int new_g = 255;
        int new_b = 255;

        int new_argb = (new_a << 24) | (new_r << 16) | (new_g << 8) | (new_b << 0);
        Console.WriteLine(new_argb);
        Console.WriteLine(Convert.ToString(new_argb, 2));

        Color c = Color.FromArgb(new_argb);
        Console.WriteLine(c);
    }
}


-- Result
-1
11111111111111111111111111111111
Color [A=255, R=255, G=255, B=255]

위 코드를 보면 new_a, new_r, new_g, new_b 변수에 각각 255라는 값을 할당했습니다.

제가 임의로 A, R, G, B값을 구성한 것입니다. (참고로 255는 A, R, G, B값의 최대치입니다.)

 

 

 

        int new_argb = (new_a << 24) | (new_r << 16) | (new_g << 8) | (new_b << 0);

이렇게 정수 형태로 된 A, R, G, B 값을 위처럼 2진수로 바꿔서 32비트의 이진수로 연결해줍니다.

 

A, R, G, B는 모두 255입니다.

255를 2진수로 바꾸면 11111111입니다.

즉, 위 코드의 결과는 11111111 11111111 11111111 11111111입니다.

(중간의 공백은 그냥 보기 쉽게 넣은 것일 뿐 아무 의미가 없으며 실제로는 존재하지 않습니다.)

 

그래서 new_argb를 콘솔에 출력하면 모두 1로 구성된 32자리의 2진수가 출력되는 것을 볼 수 있습니다.

 

 

 

        Color c = Color.FromArgb(new_argb);
        Console.WriteLine(c);


-- Result
Color [A=255, R=255, G=255, B=255]

그리고 마지막으로 32비트의 2진수는 실제로 색상으로 이용할 수 없으니 이것을 Color객체로 만들어줍니다.

여기서 사용되는게 FromArgb() method입니다.

FromArgb() method의 인자로서 ARGB값을 전달하면 Color [A=255, R=255, G=255, B=255] 처럼 Color 객체로 만들어줍니다.

 

 

 

 

 

5. Bitmap.SetPixel(x, y, color)

Bitmap.SetPixel(x, y, color) method는 Bimap 객체에 적용합니다.

그래서 Bitmap 이미지에서 (x, y)위치에 있는 픽셀을 Color 객체에 있는 ARGB값으로 바꿉니다.

 

using System;
using System.Drawing;

class MyProgram
{
    public static void Main()
    {
        Bitmap bm_img = new Bitmap("C:\\Users\\Public\\arrow.png");

        Color c = bm_img.GetPixel(0, 0);
        Console.WriteLine(c);

        int new_a = 255;
        int new_r = 255;
        int new_g = 255;
        int new_b = 255;

        int new_argb = (new_a << 24) | (new_r << 16) | (new_g << 8) | (new_b << 0);
        Color new_c = Color.FromArgb(new_argb);
        Console.WriteLine(new_c);

        bm_img.SetPixel(0, 0, new_c);
    }
}


-- Result
Color [A=255, R=153, G=217, B=234]
Color [A=255, R=255, G=255, B=255]

 

위 예시를 보면 먼저 arrow.png 이미지를 Bitmap으로 읽어와 Bitmap객체인 bm_img를 만듭니다.

 

그리고 이 이미지의 (0, 0) 위치의 Color를 출력해보면 Color [A=255, R=153, G=217, B=234] 입니다.

 

        int new_a = 255;
        int new_r = 255;
        int new_g = 255;
        int new_b = 255;

        int new_argb = (new_a << 24) | (new_r << 16) | (new_g << 8) | (new_b << 0);
        Color new_c = Color.FromArgb(new_argb);
        Console.WriteLine(new_c);
        
-- Result
Color [A=255, R=255, G=255, B=255]

위 부분에서는 A=255, R=255, G=255, B=255 값을 가진 ARGB를 구성하고 이것을 Color 객체로 변경합니다.

 

 

 

 

        bm_img.SetPixel(0, 0, new_c);

bm_img Bitmap 객체에서 x = 0, y = 0 위치에 있는 픽셀의 색상을

A=255, R=255, G=255, B=255 값을 가진 Color 객체 new_c 로 바꿉니다.

 

그러면 bm_img의 (0, 0) 위치에 있는 픽셀의 색은 A=255, R=255, G=255, B=255 로 바뀌게 되며 이것은 흰색을 의미합니다.

 

 

 

 

 

728x90
반응형
Comments