请教BMP位图色深的转换算法。如将24bit转换为16bit,8bit,以及如何反转
解决方案 »
- 如何在基于对话框的程序中分割主窗口,并且在各个区域可放置控件
- error C2228: left of '.number' must have class/struct/union type
- 如何自动关闭基于Dialog应用程序上层的多个DoModel对话框
- 那位高手帮我看看是怎么回事.
- 在Tab控件中添加flash控件,为什么在运行后flash控件的内容被tab控件覆盖掉了?
- word 进程退不出。问题在哪呢??请教!!
- 内存泄漏,在线等
- 能推荐一下介绍 vfw 的书籍等资料吗?
- 除了磁盘管理外如何设置U盘盘符的问题
- Vc编译碰到的天大难题啊
- 才学ado
- 有谁可以介绍一下_variant_t啊,或者哪里有介绍这个的文章啊
/*
//功能如下:
1. 8位位图仍然保存为8位位图
2. 16位位图将被保存为24位位图.16位位图只用于16位增强显示模式, 不在不同的系统间进行传递.
3. 24位位图仍然被保存为24位位图.
4. 32位Ddb位图将被保存为24位位图.
5. 对于16色即4位位图, 不作处理.
*/
//将Ddb位图保存成Dib位图:被保存的区域由, x, y, nWidth, nHeight来定义int CDisplayModeView::SaveBmp(char *lpFilePath,int nWidth,int nHeight,int nType)
{
CDisplayModeDoc* pDoc = GetDocument();
CDisplayModeApp *app=(CDisplayModeApp *)AfxGetApp();
ASSERT_VALID(pDoc);
if(m_nCountMathod<0)
return 0;
int i,j,nScanLine;
m_pBMI=new BITMAPINFO;
FILE *file = NULL;
file = fopen(lpFilePath, "wb");
if(file==NULL)
{
fclose(file);
delete []m_pBMI;
return -1;
}
if(m_bTmpSrcImg==NULL)
{
fclose(file);
delete []m_pBMI;
return -1;
}
switch(nType)
{
case 1://color
{
nScanLine=nWidth*4;
if(nScanLine & 3)
nScanLine=(nScanLine &~3) +4 ; DWORD dwSaveWidthBytes ;//= CalcDibWidthBytes(w, m_nBitCount);
//每行字节数必须被4整除
if(pDoc->m_DIB.GetBitCount() ==8)
// dwSaveWidthBytes=((nWidth * 8 + 31) / 32) * 4;
dwSaveWidthBytes=((nWidth * 24 + 31) / 32) * 4;
else
dwSaveWidthBytes=((nWidth * 24 + 31) / 32) * 4;
//DIB位图数据大小, 以字节为单位
DWORD dwDibBitsSize = dwSaveWidthBytes * nHeight;
//计算整个Dib文件的大小dwFileSize
DWORD dwFileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwDibBitsSize;
if(pDoc->m_DIB.GetBitCount() == 8) dwFileSize += (256 * sizeof(RGBQUAD)); //计算位图信息到位图数据间的偏移量(字节)
DWORD dwOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
//if(m_nBitCount == 8)
// if(pDoc->m_DIB.GetBitCount() ==8)
// dwOffBits += (256 * sizeof(RGBQUAD));
m_pBMI->bmiHeader.biBitCount=24;//位图的每个象素的为数,1位对应的颜色总数为2,4--16,8--256,24--16777216
m_pBMI->bmiHeader.biClrImportant=0;//指定对于显示该位图比较重要的颜色索引个数,若值为0,则所有的颜色都是重要的。
m_pBMI->bmiHeader.biClrImportant=0;//位图实际使用的颜色数
m_pBMI->bmiHeader.biCompression=0;//压宿方式
m_pBMI->bmiHeader.biClrUsed =0;
m_pBMI->bmiHeader.biHeight=nHeight;
m_pBMI->bmiHeader.biWidth=nWidth;
m_pBMI->bmiHeader.biPlanes=1;//表示目标设备的位平面数
m_pBMI->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
m_pBMI->bmiHeader.biXPelsPerMeter=0;//表示目标设备的水平分辨率
m_pBMI->bmiHeader.biYPelsPerMeter=0;//表示目标设备的垂直分辨率
m_pBMI->bmiHeader.biSizeImage =0;//nWidth*nHeight*4; BITMAPFILEHEADER bmh;//位图文件头结构
LPBITMAPINFOHEADER lpBl;//指向位图信息结构的指针
RGBQUAD rgb[256];
DWORD dwDibSize;
lpBl=(LPBITMAPINFOHEADER)m_pBMI;
if(lpBl==NULL)
{
delete[] m_pBMI;
fclose(file);
return -2; }
dwDibSize=*(LPDWORD)lpBl+256*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER); DWORD dwBmBitsSize;//BMP文件信息结构所占的字节数
dwBmBitsSize=nScanLine*nHeight;// lpBl->biWidth*lpBl->biHeight*4;//存储时位图所有象素所占的字节数
dwDibSize+=dwBmBitsSize;
lpBl->biSizeImage=dwBmBitsSize;//位图所有象素所占的字节总数 //填充BITMAPFILEHEADER结构
bmh.bfType=0x4d42;
bmh.bfSize=dwFileSize;//+sizeof(BITMAPFILEHEADER);//文件总长度 bmh.bfReserved1=0;
bmh.bfReserved2=0;
bmh.bfOffBits=dwOffBits;//(DWORD)sizeof(BITMAPFILEHEADER)+lpBl->biSize +256*sizeof(RGBQUAD);// //填充BITMAPINFOHEADER结构:8位仍然保存为8位, 其它均被保存为24位.最低显示模式为8位.
long dbWidth;
dbWidth=((nWidth * 32 + 15) / 16) * 2;
//palette
for(i=0;i<256;i++)
{
rgb[i].rgbBlue=i;
rgb[i].rgbGreen=i;
rgb[i].rgbRed=i;
rgb[i].rgbReserved =0;
}
//对于16位和32位位图, 由于数据需要重组, 所以需要重新分配内存 //指向Dib实际像素数据的指针,
BYTE* pbyDibBits = new BYTE[dwDibBitsSize];
if (pbyDibBits == NULL) return -1;
//数据索引基数
DWORD dwBaseIndex =0;// y * m_nDdbWidthBytes + ((m_nBitCount == 16) ? (x + x) : (4 * x));
DWORD dwIndexDib = (nHeight - 1) * dwSaveWidthBytes; for(i=0;i<nHeight;i++)
{
//指向Ddb内存数据的指针(行)
BYTE* pbyDdbData = m_bTmpSrcImg + dwBaseIndex; //指向Dib内存数据的指针(行)
BYTE* pbyDibData = pbyDibBits + dwIndexDib; for(j=0;j<nWidth;j++)
{
*pbyDibData++ = *pbyDdbData++; //蓝色
*pbyDibData++ = *pbyDdbData++; //绿色
*pbyDibData++ = *pbyDdbData++; //红色
pbyDdbData++;
}
dwBaseIndex += dbWidth;
dwIndexDib -= dwSaveWidthBytes;
}
fwrite((LPSTR)&bmh, sizeof(BITMAPFILEHEADER), 1, file);//文件头
fwrite(lpBl,sizeof(BITMAPINFOHEADER), 1, file);//信息头
//fwrite(rgb,sizeof(RGBQUAD)*256,1,file);//RGB
fwrite(pbyDibBits,(long)dwDibBitsSize, 1, file);//数据
fclose(file);
delete[] pbyDibBits;
delete[] m_pBMI;
break;
}
{
int j,nScanLine;
nScanLine=nWidth*4;
if(nScanLine & 3)
nScanLine=(nScanLine &~3) +4 ;
//被保存位图每行的字节数
DWORD dwSaveWidthBytes ;//= CalcDibWidthBytes(w, m_nBitCount);
//每行字节数必须被4整除
//if(pDoc->m_DIB.GetBitCount() ==8)
// dwSaveWidthBytes=((nWidth * 8 + 31) / 32) * 4;
//else
// dwSaveWidthBytes=((nWidth * 24 + 31) / 32) * 4;
dwSaveWidthBytes=((nWidth * 8 + 31) / 32) * 4;
//DIB位图数据大小, 以字节为单位
DWORD dwDibBitsSize = dwSaveWidthBytes * nHeight;
//计算整个Dib文件的大小dwFileSize
DWORD dwFileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwDibBitsSize;
//if(pDoc->m_DIB.GetBitCount() == 8)
dwFileSize += (256 * sizeof(RGBQUAD)); //计算位图信息到位图数据间的偏移量(字节)
DWORD dwOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
//if(m_nBitCount == 8)
//if(pDoc->m_DIB.GetBitCount() ==8)
dwOffBits += (256 * sizeof(RGBQUAD));
m_pBMI->bmiHeader.biBitCount=8;//位图的每个象素的为数,1位对应的颜色总数为2,4--16,8--256,24--16777216
m_pBMI->bmiHeader.biClrImportant=0;//指定对于显示该位图比较重要的颜色索引个数,若值为0,则所有的颜色都是重要的。
m_pBMI->bmiHeader.biClrImportant=0;//位图实际使用的颜色数
m_pBMI->bmiHeader.biCompression=BI_RGB;//压宿方式
m_pBMI->bmiHeader.biClrUsed =0;
m_pBMI->bmiHeader.biHeight=nHeight;
m_pBMI->bmiHeader.biWidth=nWidth;
m_pBMI->bmiHeader.biPlanes=1;//表示目标设备的位平面数
m_pBMI->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
m_pBMI->bmiHeader.biXPelsPerMeter=0;//表示目标设备的水平分辨率
m_pBMI->bmiHeader.biYPelsPerMeter=0;//表示目标设备的垂直分辨率
m_pBMI->bmiHeader.biSizeImage =0;//nWidth*nHeight; BITMAPFILEHEADER bmh;//位图文件头结构
LPBITMAPINFOHEADER lpBl;//指向位图信息结构的指针
RGBQUAD rgb[256];
DWORD dwDibSize;
lpBl=(LPBITMAPINFOHEADER)m_pBMI;
if(lpBl==NULL)
{
delete[] m_pBMI;
fclose(file);
return -2; }
dwDibSize=*(LPDWORD)lpBl+256*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER); DWORD dwBmBitsSize;//BMP文件信息结构所占的字节数
dwBmBitsSize=dwSaveWidthBytes*nHeight;// lpBl->biWidth*lpBl->biHeight*4;//存储时位图所有象素所占
dwDibSize+=dwBmBitsSize;
lpBl->biSizeImage=dwBmBitsSize;//位图所有象素所占的字节总数 bmh.bfType=0x4d42;
bmh.bfSize=dwFileSize;//dwDibSize;//+sizeof(BITMAPFILEHEADER);//文件总长度 bmh.bfReserved1=0;
bmh.bfReserved2=0;
bmh.bfOffBits=dwOffBits;//sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); ;//(DWORD)sizeof(BITMAPFILEHEADER)+lpBl->biSize +256*sizeof(RGBQUAD);//
//palette
for(int i=0;i<256;i++)
{
rgb[i].rgbBlue=i;
rgb[i].rgbGreen=i;
rgb[i].rgbRed=i;
rgb[i].rgbReserved =0;
}
LPBYTE lpNew;//,lp1;//,lp2,
lpNew=(LPBYTE)malloc((long)nWidth*nHeight);
for (i=0;i<nHeight;i++)
for (j=0;j<nWidth;j++)
{
*(lpNew+(long)i*nWidth+j)=*(m_bTmpSrcImg+(long)i*nScanLine+j*4);
} fwrite((LPSTR)&bmh, sizeof(BITMAPFILEHEADER), 1, file);//文件头
fwrite(lpBl,sizeof(BITMAPINFOHEADER), 1, file);//信息头
fwrite(rgb,sizeof(RGBQUAD)*256,1,file);//RGB
fwrite(lpNew,(long)nHeight*nWidth, 1, file);//数据
fclose(file);
delete[] m_pBMI;
free(lpNew);
break;
}
}
return 1;
}