RAW는 Debayer + Low-Pass filter 등 카메라의 이미지 프로세서(Image Processor)에 의한 센서 보간을 거치지 않은 이미지를 의미한다.
RAW 파일은 일반적인 이미지 뷰어로는 열어보기가 힘들고, RGB 및 YUV 색상을 기반으로 하는 영상 및 이미지 파일의 규약에 맞춰서 후가공을 거쳐야만 한다.
RAW 이미지에서는 픽셀값이 빨강, 녹색, 파랑 중 한가지의 값만 가지고 (베이어 색상), EV 스톱 단위의 상대치로 저장된다. (장면 참조형 입력, Scene-Referred Input) 색 공간에 맞춰진 상태가 아니므로 절대적인 흰색 레벨이나 검은색 레벨도 정해져있지 않다.
RAW에서 비트수는 단순히 색상의 단계를 뜻하는 것이 아니라 저장되는 노출 단계의 수를 의미한다. 예를 들어, 10비트 RAW인 경우에는 10EV의 다이나믹 레인지를 가지고 있고, 12비트 RAW인 경우에는 12EV, 14비트 RAW인 경우에는 14EV의 다이나믹 레인지를 가진다.
.raw 이미지를 열기 위해서는 RGB값들을 불러와 비트맵 이미지로 변환한 뒤 Open하면 된다.
이를 위해서는 이미지를 불러오는 버튼과, 이미지를 출력하는 컨트롤이 필요하다.
다음은 구현 코드의 일부이다.
// ImageDlg.cpp : 구현 파일
//
#include "stdafx.h"
#include "Image.h"
#include "ImageDlg.h"
#include "afxdialogex.h"
#include <math.h>
void CImageDlg::OnBnClickedButtonOpen()
{
// 파일 열어서 bitmap으로 출력
CFileDialog fDlg(TRUE);
fDlg.DoModal();
CFile Rfile;
if (!Rfile.Open(fDlg.GetPathName(), CFile::modeRead))
{
MessageBox(_T("Can't Open Image File!"));
return;
}
memset(m_original, 0, IMAGE_SIZE);
UINT FileLength = (UINT)Rfile.GetLength();
unsigned char*ps = new unsigned char[FileLength];
Rfile.Read(ps, FileLength);
for (int y = 0; y < IMAGE_HEIGHT; y++)
{
for (int x = 0; x < IMAGE_WIDTH; x++)
{
m_original[y * IMAGE_WIDTH + x] = ps[y * IMAGE_WIDTH + x];
}
}
delete[] ps;
if(bmpInfo != nullptr)
{
delete bmpInfo;
bmpInfo = nullptr;
}
int rwsize = (((512) + 31) / 32 * 4);
bmpInfo = (BITMAPINFO*)malloc(sizeof(BITMAPINFO) + IMAGE_HEIGHT * sizeof(RGBQUAD));
bmpInfo->bmiHeader.biBitCount = 8;
bmpInfo->bmiHeader.biClrImportant = IMAGE_WIDTH;
bmpInfo->bmiHeader.biClrUsed = IMAGE_WIDTH;
bmpInfo->bmiHeader.biCompression = 0;
bmpInfo->bmiHeader.biPlanes = 1;
bmpInfo->bmiHeader.biSize = 40;
bmpInfo->bmiHeader.biSizeImage = rwsize * IMAGE_WIDTH;
bmpInfo->bmiHeader.biHeight = -IMAGE_HEIGHT;
bmpInfo->bmiHeader.biWidth = IMAGE_WIDTH;
bmpInfo->bmiHeader.biXPelsPerMeter = 0;
bmpInfo->bmiHeader.biYPelsPerMeter = 0;
for (int i = 0; i < 512; i++) {
bmpInfo->bmiColors[i].rgbRed = bmpInfo->bmiColors[i].rgbGreen
= bmpInfo->bmiColors[i].rgbBlue = i;
bmpInfo->bmiColors[i].rgbReserved = 0;
}
StretchDIBits(m_memDC->GetSafeHdc(),
0, 0, m_rtViewer.Width(), m_rtViewer.Height(), 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT,
m_original, bmpInfo, DIB_RGB_COLORS, SRCCOPY);
Invalidate(FALSE);
}