티스토리 뷰

[MFC 이미지 색 반전 (Invert color image)]

 

오늘은 원본 이미지를 출력 후

원본 이미지의 색상을 반전시켜서

바로 옆에 색상을 반전시킨 이미지를 출력시키는 예제를 만들어보겠습니다.

 

 

 

[결과 사진]

왼쪽은 원본사진이고 오른쪽은 색상을 반전시킨 사진입니다.

 

 

 

구현은 색상 최댓값인 255에서 현재 픽셀 값을 빼고

다시 그 픽셀에 뺀 값을 저장하는 식으로 구현했습니다.

 


[코드 설명]

먼저 변수를 만들어주기 위해

Dlg.h 헤더 파일에 가줍니다.

원본 이미지를 저장할 변수와

색이 반전된 이미지를 저장할 변수를 추가시켜줍니다.

 

 

원본 이미지를 저장할 변수 -> m_image

색이 반전된 이미지를 저장할 변수 -> invert_image

// CInvertImageDlg 대화 상자
class CInvertImageDlg : public CDialogEx
{
private:
   CImage m_image; // 원본 이미지 변수
   CImage invert_image; // 반전 이미지 변수
cs

 

 

다음은 소스 파일에 코드를 추가해보겠습니다.

Dlg.cpp 소스 파일에 가줍니다.

OnInitDialog() 위치에 가서 아래의 코드를 추가시켜줍니다.

m_image.Load(L"test.bmp");

아까 전 헤더 파일에서 추가시켜준

m_image 변수에

사용자가 원하는 외부 이미지를 로드시켜주는 코드입니다.

// CInvertImageDlg 메시지 처리기
 
BOOL CInvertImageDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
 
    SetIcon(m_hIcon, TRUE);         
    SetIcon(m_hIcon, FALSE);        
 
    m_image.Load(L"test.bmp"); // 외부 이미지 로드
 
    invert_image.Create(m_image.GetWidth(), m_image.GetHeight(), m_image.GetBPP(), 0);
 
    return TRUE;  
}
cs

여기서 주의해야 할 점은

해당 이미지 이름이 test로 되어있어야 합니다.

그리고 해당 소스파일들이 있는 폴더에 넣어주서야 합니다.

만약에 이미지가 bmp 파일로 안되어있으면

bitmap 오류라고 메시지가 뜨실 수 있습니다~!

 

 

다음 OnInitDialog 아래에 있는

OnPaint() 위치로 가줍니다.

IsIconic()은 다이얼로그가 최소화될 때를 말합니다.

그래서 그림을 그려주려면 else 문에 코드를 추가시켜줘야 하는데

아래 코드를 추가시켜줍니다.

m_image.Draw(dc, 10, 10);

프로그램의 윈도 창 (10,10) 좌표를

시작점으로 해당 이미지를 그려주는 코드입니다.

void CInvertImageDlg::OnPaint()
{
    CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.
 
    if (IsIconic())
    {
        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
 
        // 클라이언트 사각형에서 아이콘을 가운데에 맞춥니다.
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1/ 2;
        int y = (rect.Height() - cyIcon + 1/ 2;
 
        // 아이콘을 그립니다.
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        m_image.Draw(dc, 1010); // 좌표(10,10) 기준으로 이미지 출력
        //CDialogEx::OnPaint();
    }
}
cs

여기서 주의해야 할 점은

if문 안에 있었던

CPaintDC dc(this); 를

if문 위로 빼주셔야 합니다.

그리고 else 문에

CDialogEx::OnPaint(); 부분을

주석처리시켜줍니다.

 

 

다음은 다이얼로그를 편집해줘야 합니다.

리소스 뷰에 Dialog로 가서

버튼 하나를 추가시켜줍니다.

추가시켜준 후 버튼 이벤트 함수를 만들어주기 위해서

버튼을 더블클릭해줍니다.

그러면 이벤트 처리를 해줄 함수가 dlg.cpp 파일 안에

하나 만들어지는데

거기에 아래의 코드를 추가시켜줍니다.

CClientDC dc(this);

부터

invert_image.Draw(dc, 500, 10);

까지 추가시켜줍니다.

void CInvertImageDlg::OnBnClickedInvertBtn()
{
    CClientDC dc(this);
 
    COLORREF temp_color;
 
    for (int y = 0; y < m_image.GetHeight(); y++) { // 이미지의 세로 픽셀값 만큼
        for (int x = 0; x < m_image.GetWidth(); x++) { // 이미지의 가로 픽셀값 만큼
            temp_color = m_image.GetPixel(x, y); // 현재 픽셀의 색상을 얻어 저장
 
            int r = GetRValue(temp_color); // 현재 픽셀의 RGB중 R값을 저장
            int g = GetGValue(temp_color); // 현재 픽셀의 RGB중 G값을 저장
            int b = GetBValue(temp_color); // 현재 픽셀의 RGB중 B값을 저장
 
            int new_r = 255 - r; // 얻은 R값을 최대값에 빼서 반전값을 얻음
            int new_g = 255 - g; // 얻은 G값을 최대값에 빼서 반전값을 얻음
            int new_b = 255 - b; // 얻은 B값을 최대값에 빼서 반전값을 얻음
 
            invert_image.SetPixel(x, y, RGB(new_r, new_g, new_b));
           // 반전된 RGB 값으로 새로운 이미지에 SetPixel 해줌
        }
    }
    invert_image.Draw(dc, 50010); // 좌표(500,10)을 기준으로 이미지 출력
}
 
cs

해당 코드 설명

-> temp_color : 잠시 컬러를 저장해줄 COLORREF 변수입니다.

 

m_image.GetHeight(); : 원본이미지의 높이 값을 알 수 있는 함수입니다.

 

m_image.GetWidth();  : 원본이미지의 가로 값을 알 수 있는 함수입니다.

 

m_image.GetPixel(x, y); : 원본이미지의 (x, y) 좌표에있는 픽셀 색상을 얻을 수 있는 함수입니다.

 

GetRValue(temp_color); : temp_color에 저장되어있는 색상 중 R값만 얻어 올 수 있는 함수입니다.

GetGValue와 GetBValue 또한 마찬가지 역할을 합니다.

 

int new_r = 255 - r; 는 색상 최댓값인 255에서 원본이미지로부터 얻은 r값을 빼주는 역할을 합니다.

int new_g = 255 - g; 와 int new_b = 255 - b; 또한 같은 역할을 합니다.

 

invert_image.SetPixel(x, y, RGB(new_r, new_g, new_b));

: 255에서 뺀 rgb 값을 새로운 이미지(invert_image)에

setpixel을 사용해 색상을 넣어주는 역할을 합니다.

 

invert_image.Draw(dc, 500, 10);

: 마지막으로 새로운 이미지를 (500,0) 좌표에 그려주는 코드입니다.

이미지가 크면 좌푯값을 수정해서 적어주시면 됩니다.

 

프로그램을 실행시켜주시면

원본 이미지가 뜨고

버튼을 눌러주시면 색상이 반전된 이미지가 나오게 됩니다~:)