이전에 만들었던 프로그램은 Gray Scale(RAW) 기반으로 만들었습니다.
이번에는 CImage를 사용하여 간편하게 Color기반으로 바꿔보도록 하겠습니다.
>>Color기반코드 틀
- Doc에 전역변수 선언
- 2차원 동적메모리 생성
unsigned char** malloc2D(int h, int w) { // TODO: 여기에 구현 코드 추가. unsigned char** memory; memory = (unsigned char**)malloc(h * sizeof(unsigned char*)); for (int i = 0; i < h; i++) memory[i] = (unsigned char*)malloc(w * sizeof(unsigned char)); // 초기화(클리어) for (int i = 0; i < h; i++) for (int k = 0; k < w; k++) memory[i][k] = 255; return memory; }
- 2차원 동적 메모리 해제
void free2D(unsigned char** memory, int h) { // TODO: 여기에 구현 코드 추가. if (memory != NULL) { for (int i = 0; i < h; i++) free(memory[i]); free(memory); } }
- 각 R,G,B값을 따로 받습니다.
if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE; // TODO: 여기에 특수화된 작성 코드를 추가합니다. // 입력 메모리 해제 (R G B) free2D(m_InputImageR, m_inH); free2D(m_InputImageG, m_inH); free2D(m_InputImageB, m_inH); // 컬러파일을 읽는 CImage 라이브러리 활용 CImage bitmap; bitmap.Load(lpszPathName); // 입력 데이터 Load // 중요! 이미지의 높이, 폭 계산 m_inH = bitmap.GetHeight(); m_inW = bitmap.GetWidth(); //메모리 할당 m_InputImageR = malloc2D(m_inH, m_inW); m_InputImageG = malloc2D(m_inH, m_inW); m_InputImageB = malloc2D(m_inH, m_inW); COLORREF px; // 한점(R G B) _ (컬러레퍼런스) _ MFC라이브러리 for (int i = 0; i < m_inH; i++) { for (int k = 0; k < m_inW; k++) { px = bitmap.GetPixel(k, i); // 픽셀 받아오기 (행, 열) m_InputImageR[i][k] = (unsigned char)GetRValue(px); m_InputImageG[i][k] = (unsigned char)GetGValue(px); m_InputImageB[i][k] = (unsigned char)GetBValue(px); } } return TRUE;
- grayscale때와 달리 각 픽셀 세가지(R,G,B)들을 각각 free 해줍니다.
{ // TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다. free2D(m_InputImageR, m_inH); // 임의로 만들어둔 2차원 free(); free2D(m_OutputImageR, m_outH); free2D(m_InputImageG, m_inH); // 임의로 만들어둔 2차원 free(); free2D(m_OutputImageG, m_outH); free2D(m_InputImageB, m_inH); // 임의로 만들어둔 2차원 free(); free2D(m_OutputImageB, m_outH); CDocument::OnCloseDocument(); }
해당Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다. int RR, GG, BB; for (int i = 0; i < pDoc->m_inH; i++) { for (int k = 0; k < pDoc->m_inW; k++) { RR = pDoc->m_InputImageR[i][k]; GG = pDoc->m_InputImageG[i][k]; BB = pDoc->m_InputImageB[i][k]; pDC->SetPixel(k + 5, i + 5, RGB(RR, GG, BB)); } } for (int i = 0; i < pDoc->m_outH; i++) { for (int k = 0; k < pDoc->m_outW; k++) { RR = pDoc->m_OutputImageR[i][k]; GG = pDoc->m_OutputImageG[i][k]; BB = pDoc->m_OutputImageB[i][k]; pDC->SetPixel(pDoc->m_inW + k + 20, i + 5, RGB(RR, GG, BB)); } }
// TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다. if (m_OutputImageR == NULL) { MessageBox(NULL, L"파일이 열리지 않았습니다.", L"", 0); return FALSE; } // .PNG 로 저장하는 관례적인 코드 static TCHAR BASED_CODE szFilter[] = _T("PNG파일(*.PNG) | *.png | 모든파일(*.*) | *.* ||"); CFileDialog SaveDlg(TRUE, _T("*.png"), _T(""), OFN_HIDEREADONLY, szFilter); if (SaveDlg.DoModal() != IDOK) return FALSE; CImage bitmap; bitmap.Create(m_outW, m_outH, 32); // 빈 파일 만들기(행, 열, 32); // CImage는 i랑 k가 반대임. COLORREF px; unsigned char RR, GG, BB; for (int i = 0; i < m_outW; i++) { for (int k = 0; k < m_outH; k++) { RR = m_OutputImageR[k][i]; GG = m_OutputImageG[k][i]; BB = m_OutputImageB[k][i]; px = RGB(RR, GG, BB); bitmap.SetPixel(i, k, px); } } bitmap.Save(SaveDlg.GetPathName(), Gdiplus::ImageFormatPNG); // MFC에서는 PNG포멧을 지원한다. return TRUE; // 리턴 True해줘야 정상저장됨
- 현재 해당화면을 전체화면으로 해놓는 코드를 적용했다.
this->ShowWindow(SW_SHOWMAXMIZED);