티스토리 뷰
[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, 10, 10); // 좌표(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, 500, 10); // 좌표(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) 좌표에 그려주는 코드입니다.
이미지가 크면 좌푯값을 수정해서 적어주시면 됩니다.
프로그램을 실행시켜주시면
원본 이미지가 뜨고
버튼을 눌러주시면 색상이 반전된 이미지가 나오게 됩니다~:)
'프로그래밍 > MFC 프로그래밍' 카테고리의 다른 글
[MFC C++] 이미지 RGB 분리 (2) | 2020.01.19 |
---|---|
MFC 이미지 회전시키기(각도 조절) (2) | 2020.01.17 |
MFC 픽셀값 사용해서 이미지 확대 시키기 (0) | 2020.01.13 |
MFC 이미지 회전 시키기 (0) | 2020.01.10 |
MFC 히스토그램 그리기 (8) | 2020.01.07 |