BMP的8位位图转换24位位图

#define WIDTHBYTES(bits) (((bits)+31)/32*4)  //一行的位数
/******************************************************************************
*函数功能:获取位图信息
*函数声明:
   BOOL GetNormalBmpInfo(
   CString m_strFile,  -位图路径
   nWidth,  -位图宽度
   nHeight:位图高度
   biBitCount:位数
   pbi,获取位图地址
   lpBits:获取位图的实际数据
    )
******************************************************************************/
bool GetNormalBmpInfo(CString m_strFile,int &nWidth,int &nHeight, int &iBitCount,BITMAPINFO**pbi,void** lpBits)// 获取标准BMP文件的长度和高度
{
CFile file;
if( !file.Open( m_strFile, CFile::modeRead) )
return false;
BITMAPFILEHEADER bmfHeader;
//读位图文件头信息
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
return false;
//判断是否是BMP
if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
return false;
//读位图头信息
BITMAPINFOHEADER bmiHeader;
if (file.Read((LPSTR)&bmiHeader, sizeof(bmiHeader)) !=sizeof(bmiHeader))
return false;
//获得大小信息,并显示
nWidth = bmiHeader.biWidth;
nHeight = bmiHeader.biHeight;
iBitCount = bmiHeader.biBitCount;
int numQuad = 0;
if(bmiHeader.biBitCount < 24)小于24位有调色板
{
numQuad = 1 << bmiHeader.biBitCount;
//为图像信息pbi申请空间
//* pbi=(BITMAPINFO*)malloc(sizeof(BITMAPINFOHEADER)+numQuad*sizeof(RGBQUAD));
* pbi=(BITMAPINFO*)new BYTE[sizeof(BITMAPINFOHEADER)+numQuad*sizeof(RGBQUAD)];
memcpy(*pbi,&bmiHeader,sizeof(bmiHeader));
RGBQUAD* quad =(RGBQUAD*)((BYTE*)(*pbi)+sizeof(BITMAPINFOHEADER));
//读取调色板
if(numQuad!=0)
{
file.Read(quad,sizeof(RGBQUAD)*numQuad);
}
}
DWORD fileLength =  bmiHeader.biWidth* bmiHeader.biHeight;//总文件大小
DWORD  size = fileLength -sizeof(BITMAPFILEHEADER);//文件大小-文件头结构体的大小,此时你会发现,文件头的大小的确是14字节
bmiHeader.biSizeImage = file.GetLength() - bmfHeader.bfOffBits;
//int l_width = WIDTHBYTES( bmiHeader.biWidth* bmiHeader.biBitCount);//计算位图的实际宽度并确保它为32的倍数
//long nSize = l_width*bmiHeader.biHeight;
*lpBits = (BYTE*)new BYTE[bmiHeader.biSizeImage];
file.Read((void*)(*lpBits), bmiHeader.biSizeImage);//通过读取,把读出的数据存入刚才分配的内存之中
file.Close();//文件操作完成之后关闭文件
return true;
}

/******************************************************************************

*函数功能:将8位位图转换为24位位图
*函数声明:
   BOOL Bitmap8To24(
    BYTE* srcImage,  -指向源图像的像素数据的指针
    BYTE* dstImage,  -指向目的图像的像素数据的指针
BITMAPINFO* lpbi,=位图信息地址
    LONG imageWidth, -源图像的宽度(像素数)
    LONG imageHeight -源图像的高度(像素数)
    )
******************************************************************************/
BOOL CDIB::Bitmap8To24(BYTE* srcImage,BYTE* dstImage,BITMAPINFO* lpbi,LONG imageWidth,LONG imageHeight)
{
LONG lLineBytes24=((imageWidth*24+31)/32*4);
LONG lLineBytes8=((imageWidth*8+31)/32*4);
int n,j;
/*for(int i=0;i<imageHeight;i++)
{
for(j=0,n=0;j<lLineBytes8;j++,n++)//这部分为转换成灰度图像
{
BYTE gray=*(srcImage+lLineBytes8*i+j);
*(dstImage+lLineBytes24*i+n)=gray;
n++;
*(dstImage+lLineBytes24*i+n)=gray;
n++;
*(dstImage+lLineBytes24*i+n)=gray;
}
}*/


//因为24位是用三位表示一个颜色(顺序是BGR),没有调色板,而8位的是一位表示一个颜色信息在调色板中的偏移量
RGBQUAD *pRgb = (RGBQUAD *)((BYTE*)lpbi+sizeof(BITMAPINFOHEADER));
for( int i=0; i<imageHeight; i++)
{
for( j=0, n=0; j<lLineBytes8; j++)
{
int num = *(srcImage+lLineBytes8*i+j);//获取8位中调色板信息的偏移量
//将颜色信息写入24位指针指向的地址(为了保证dstBits始终指向首地址,故不写成dst=...)
*(dstImage+lLineBytes24*i+n)=pRgb[num].rgbBlue;
n++;
*(dstImage+lLineBytes24*i+n)=pRgb[num].rgbGreen;
n++;
*(dstImage+lLineBytes24*i+n)=pRgb[num].rgbRed;
n++;
}
}
return true;

}

注意:上面两个函数已经根据8位图信息转为24位实际数据,接下来可以自己加入24位头部信息生成图像。

参考地址:http://blog.csdn.net/poonjun/article/details/3701641

http://blog.csdn.net/yjn43422757/article/details/6493658

http://blog.csdn.net/yjn43422757/article/details/6493662


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
24位图转换8位位图的过程中,需要用到调色板。调色板是一个包含256种颜色的表格,每个颜色都由三个8位组成的RGB值来表示。具体的转换步骤如下: 1. 创建一个空白的8位位图,并设置它的宽度和高度与原始24位图相同。 2. 创建一个调色板,其中包含256种颜色。可以使用ColorPalette类来创建调色板。 3. 遍历原始24位图的每个像素,将它的RGB值转换成一个0到255之间的整数,然后将该整数作为调色板中对应颜色的索引,将索引值写入新的8位位图中。 4. 将调色板与新的8位位图相关联,使用Bitmap类的SetPixel和GetPixel方法可以完成这一步操作。 5. 最后保存新的8位位图即可。 下面是一个C#代码示例,可以将24位图转换8位位图: ```csharp public static Bitmap ConvertTo8bpp(Bitmap bmp) { // 创建一个新的8位位图 Bitmap newBmp = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format8bppIndexed); // 创建调色板 ColorPalette pal = newBmp.Palette; for (int i = 0; i < 256; i++) { pal.Entries[i] = Color.FromArgb(i, i, i); } newBmp.Palette = pal; // 遍历原始位图的每个像素,并将RGB值转换成索引 for (int y = 0; y < bmp.Height; y++) { for (int x = 0; x < bmp.Width; x++) { Color color = bmp.GetPixel(x, y); int index = (int)(0.299 * color.R + 0.587 * color.G + 0.114 * color.B); newBmp.SetPixel(x, y, Color.FromArgb(index, index, index)); } } return newBmp; } ``` 在这个示例中,使用了YUV颜色空间的转换公式将RGB值转换成了索引。可以根据具体需求使用不同的转换公式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值