8位位图转换成24位位图

8位位图与24位位图的区别就在于8位的有调色板,而24位的没有。调色板信息是按(BGRA)顺序存放的,每4位是一个调色板项,共有256个调色板,故只能显示256种颜色,其中A始终为0。位图数据区则是存储的调色板索引,比如0,1,2……按索引获取颜色。

24位的则不然,24位位图没有调色板,数据区存储的就是BGR颜色数据,每3位为一个像素点的颜色,所以可以显示2的24次方种颜色。

转换过程很容易,就是按照8位位图索引取出调色板中的数据,把A舍去,把其他的按顺序存储到24位图像的数据区,在数据区前加上位图的头就OK了,代码如下:

void CDib::ConverTo24Bit()
{
 LPBITMAPINFOHEADER  lpbi;
 if(!hdib)
  return;
 lpbi = (BITMAPINFOHEADER*)hdib;//hdib是成员变量,指向已打开的位图信息首地址
 int height = lpbi->biHeight;
 //两个宽度
 LONG lLineBytes24=((lpbi->biWidth*24+31)/32*4);
 LONG lLineBytes8=((lpbi->biWidth*8+31)/32*4);
 //源图像的指针,申请一块足够大的内存
 BYTE* srcBits ;//= (BYTE*)malloc(lLineBytes8*height);
 //使其指向源图像的图像数据起始地址
 srcBits = (BYTE*)lpbi+sizeof(BITMAPINFOHEADER)+PaletteSize();
 //转换后的图像数据指针
 BYTE* dstBits = (BYTE*)malloc(lLineBytes24*height);
 //调色板信息
 RGBQUAD *pRgb = (RGBQUAD *)((BYTE*)lpbi+sizeof(BITMAPINFOHEADER));
 //通过循环,使8位BMP中的颜色信息转换为24位
 //因为24位是用三位表示一个颜色(顺序是BGR),没有调色板,而8位的是一位表示一个颜色信息在调色板中的偏移量
 for( int i=0; i<height; i++)
 {
  for(int j=0, n=0; j<lLineBytes8; j++)
  {
   int num = *(srcBits+lLineBytes8*i+j);//获取8位中调色板信息的偏移量
   //将颜色信息写入24位指针指向的地址(为了保证dstBits始终指向首地址,故不写成dst=...)
   *(dstBits+lLineBytes24*i+n)=pRgb[num].rgbBlue;
   n++;
   *(dstBits+lLineBytes24*i+n)=pRgb[num].rgbGreen;
   n++;
   *(dstBits+lLineBytes24*i+n)=pRgb[num].rgbRed;
   n++;
  }
 }
 //24位BMP的信息头
 BITMAPINFOHEADER bi;
 bi.biBitCount=24;
 bi.biClrImportant=0;
 bi.biClrUsed=0;
 bi.biCompression=0L;
 bi.biHeight=Height();
 bi.biPlanes=1;
 bi.biSize=sizeof(BITMAPINFOHEADER);
 bi.biSizeImage=Height()*lLineBytes24;
 bi.biWidth=Width();
 bi.biXPelsPerMeter=0;
 bi.biYPelsPerMeter=0;
 //设置BMP信息头和数据信息函数
 SetBitmapinfoAndBits(bi, dstBits);//函数功能为把信息头和数据信息合并,存储在hdib指针指向的区域内
 CString FileName;
 strFileName.Delete(strFileName.GetLength()-4, 4);
 FileName.Format("%s的24位图.bmp",strFileName);
 SaveFile(FileName);//把hdib指向的区域写入到文件
 //收尾清除指针内存
 //free(srcBits);
 srcBits = NULL;
 free(dstBits);
 dstBits = NULL;
 AfxMessageBox("已经转换成24位,另存为:"+FileName);
}

 

关于读取和设置信息头,保存部分会写在别的地方

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
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值转换成了索引。可以根据具体需求使用不同的转换公式。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值