[MFC] GrayScale 기반 -> Color기반으로 바꾸기

Sireal·2021년 9월 1일
0

C++/Win32/MFC

목록 보기
3/12
post-thumbnail

이전에 만들었던 프로그램은 Gray Scale(RAW) 기반으로 만들었습니다.

이번에는 CImage를 사용하여 간편하게 Color기반으로 바꿔보도록 하겠습니다.
>>Color기반코드 틀


GrayScale, Color

  • GrayScale은 우리가 흔히 알고있는 흑백사진
  • Color는 컬러사진, RGB의 뜻은 Red, Green, Blue _ 3원색
  • Color를 GrayScale화 하려면, RGB의 합의 평균을 RGB값에 넣어주면 됨.

메모리 관련 개인코드

  • 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);
	}
}

실행 및 파일열기_Doc::OnOpenDocument()

  • 각 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;

사용종료 및 파일닫기_Doc::OnCloseDocument()

  • 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();
}

화면 출력_View::OnDraw()

	해당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));
		}
	}

파일 저장_Doc::OnSaveDocument()

// 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해줘야 정상저장됨

해당 프레임(화면) 설정_CChildFrame::ActiveFrame()

  • 현재 해당화면을 전체화면으로 해놓는 코드를 적용했다.
this->ShowWindow(SW_SHOWMAXMIZED);

profile
🚄계속 앞으로🚄

0개의 댓글