一个读取raw格式图像数据并显示的函数,但是显示不正确,哪位高手给看看问题出在哪,或者是哪里可能有问题。谢谢
/*************************************************************************
*
* Function: ReadRAWFile (CFile&)
*
* Purpose: Reads in the specified RAW file into a global chunk of
* memory.
*
* Returns: A handle to a dib (hDIB) if successful.
* NULL if an error occurs.
*
* Comments: BITMAPFILEHEADER is stripped off of the DIB.
* Everything from the end of the BITMAPFILEHEADER structure
* on is returned in the global memory handle.
*
**************************************************************************/
HDIB ReadRAWFile(CFile& file)
{
double min,max;
int width,height; CRawdlg dlg;
if (dlg.DoModal() != IDOK) return FALSE;
width=dlg.m_width;
height=dlg.m_height;
//Allocate memory for the image
DWORD dwImageSize = width*height*12;// 12=DIBChannels
BYTE* pImageData = new BYTE[dwImageSize]; file.Read(pImageData,dwImageSize);
// Setup the DIB with the correct details
BITMAPINFO bmi;
BITMAPINFOHEADER& bih = bmi.bmiHeader;
ZeroMemory(&bih, sizeof(BITMAPINFOHEADER));
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = width;
bih.biHeight= height;
bih.biCompression = BI_RGB;
bih.biPlanes = 1;
bih.biBitCount = 24; // Allocate memory for DIB
DWORD dwBmpBitsSize = WIDTHBYTES(width*24)*height;
HDIB hDIB = (HDIB) ::GlobalAlloc(GHND, bih.biSize + dwBmpBitsSize);
if (hDIB == 0)
{
TRACE(_T("Could not allocate memory for the DIB while loading from file!\n"));
delete [] pImageData;
return NULL;
} LPSTR pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
if (pDIB == 0)
{
TRACE(_T("Could not lock memory for the DIB while loading from file!\n"));
delete [] pImageData;
return NULL;
} //Copy over the header to the DIB
CopyMemory(pDIB, &bmi.bmiHeader, bih.biSize); //Copy the DIB bits from the user buffer into the DIB
BYTE* pBmp = (BYTE*) (pDIB + bih.biSize);
for (int j=0; j<height; j++)
{
int nDepthInOffset = j*width*3;
int nDepthOutOffset = (height-j-1)*WIDTHBYTES(width*24);
for (int i=0; i<width; i++)
{
int nInOffset = nDepthInOffset + i*3;
int nOutOffset = nDepthOutOffset + i*3;
pBmp[nOutOffset] = pImageData[nInOffset];
pBmp[nOutOffset+1] = pImageData[nInOffset+1];
pBmp[nOutOffset+2] = pImageData[nInOffset+2];
}
} //Delete the memory used to load the jpeg prior to transfering to the DIB
delete [] pImageData; ::GlobalUnlock((HGLOBAL) hDIB);
return hDIB;}
/*************************************************************************
*
* Function: ReadRAWFile (CFile&)
*
* Purpose: Reads in the specified RAW file into a global chunk of
* memory.
*
* Returns: A handle to a dib (hDIB) if successful.
* NULL if an error occurs.
*
* Comments: BITMAPFILEHEADER is stripped off of the DIB.
* Everything from the end of the BITMAPFILEHEADER structure
* on is returned in the global memory handle.
*
**************************************************************************/
HDIB ReadRAWFile(CFile& file)
{
double min,max;
int width,height; CRawdlg dlg;
if (dlg.DoModal() != IDOK) return FALSE;
width=dlg.m_width;
height=dlg.m_height;
//Allocate memory for the image
DWORD dwImageSize = width*height*12;// 12=DIBChannels
BYTE* pImageData = new BYTE[dwImageSize]; file.Read(pImageData,dwImageSize);
// Setup the DIB with the correct details
BITMAPINFO bmi;
BITMAPINFOHEADER& bih = bmi.bmiHeader;
ZeroMemory(&bih, sizeof(BITMAPINFOHEADER));
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = width;
bih.biHeight= height;
bih.biCompression = BI_RGB;
bih.biPlanes = 1;
bih.biBitCount = 24; // Allocate memory for DIB
DWORD dwBmpBitsSize = WIDTHBYTES(width*24)*height;
HDIB hDIB = (HDIB) ::GlobalAlloc(GHND, bih.biSize + dwBmpBitsSize);
if (hDIB == 0)
{
TRACE(_T("Could not allocate memory for the DIB while loading from file!\n"));
delete [] pImageData;
return NULL;
} LPSTR pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
if (pDIB == 0)
{
TRACE(_T("Could not lock memory for the DIB while loading from file!\n"));
delete [] pImageData;
return NULL;
} //Copy over the header to the DIB
CopyMemory(pDIB, &bmi.bmiHeader, bih.biSize); //Copy the DIB bits from the user buffer into the DIB
BYTE* pBmp = (BYTE*) (pDIB + bih.biSize);
for (int j=0; j<height; j++)
{
int nDepthInOffset = j*width*3;
int nDepthOutOffset = (height-j-1)*WIDTHBYTES(width*24);
for (int i=0; i<width; i++)
{
int nInOffset = nDepthInOffset + i*3;
int nOutOffset = nDepthOutOffset + i*3;
pBmp[nOutOffset] = pImageData[nInOffset];
pBmp[nOutOffset+1] = pImageData[nInOffset+1];
pBmp[nOutOffset+2] = pImageData[nInOffset+2];
}
} //Delete the memory used to load the jpeg prior to transfering to the DIB
delete [] pImageData; ::GlobalUnlock((HGLOBAL) hDIB);
return hDIB;}
raw图像的大小通过对话框用户输入(width=dlg.m_width; height=dlg.m_height;)得到,如果是float数据类型,那么这个DWORD dwImageSize = width*height*x中的x应该取多少呢,也就是读入的数据内存应该分配多大呢?
但是”一般就是类似“inch”、“cm”这样的选项,这些单位下的width和height数据是可以为float型的,但通常应该搭配有分辨率的信息,如DPI(dot per inch)。”,这个和我强调的数据类型不一样,你所讨论的是8bit int型raw数据, 这种数据我已经可以打开并显示。我现在要打开的是float(32bit)和double(64bit)型raw数据,换句话说他们是按照这两种数据类型保存的,不是整数int型。
24bit彩色 - R(8bit)、G(8bit)、B(8bit)
32bit彩色 - R(8bit)、G(8bit)、B(8bit)、A(8bit,颜色的alpha 通道,透明信息)
48bit彩色 - R(16bit)、G(16bit)、B(16bit)至于64bit的数据,我想可能在48bit基础上多一个16bit的A channel吧。不晓得我理解的这些类型跟你说的类型有没有共通的地方。
打开raw数据时除了长和宽之外还需要另一个重要的参数就是数据类型,我所指的就是这个。这个数据类型可以是8bit int型,也可以是float(32bit)和double(64bit)型。
对于8bit型,一个像素只占用一个字节;32bit,一个像素占用4个字节。现在的问题是我可以打开8bit的数据,但是32bit的数据如何打开,应该是需要一个转换。
DWORD color = (DWORD)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16));
从这个color值分析出R、G、B则通过如下
R = (BYTE)(color);
G = (BYTE)(((WORD)(color)) >> 8);
B = (BYTE)((rgb)>>16);至于float和double类型就真不知道该怎么处理,看来还得学习啊!