在内存重构Bitmap的文件结构,并转换为Bitmap对象

Bitmap文件的基本结构在MSDN里描述的很详细,主要由四部分组成:

文件头:BITMAPFILEHEADER

信息头:BITMAPINFOHEADER

调色板:RGBQUAD

数据段

当像素大于8位时,就没有调色板了。

 

好了下面是代码。

输入参数dwWidth、dwHeight、wBitPerPixel、pBits.

int i; int width=dwWidth; int height=dwHeight; int bitcount=wBitsPerPixel;//像素的位数1,4,8,16,24,32 int index = 0; unsigned char rgbquad[4]; BITMAPFILEHEADER bitmapFileHeader; BITMAPINFOHEADER bitmapInfoHeader; DWORD widthbytes = ((width*bitcount+31)/32)*4;//每行都是4的倍数  //文件头到数据的偏移量,主要是计算调色板的内存大小  switch(bitcount) { case 1: index = 2; bitmapFileHeader.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 2*4); break; case 4: index = 16; bitmapFileHeader.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 16*4); break; case 8: index = 256; bitmapFileHeader.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)); break; case 24: case 32: index = 0; bitmapFileHeader.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)); break; default: break; } //构造Bitmap文件头BITMAPFILEHEADER bitmapFileHeader.bfType = 0x4d42; bitmapFileHeader.bfReserved1 = 0; bitmapFileHeader.bfReserved2 = 0; bitmapFileHeader.bfSize = (DWORD)(bitmapFileHeader.bfOffBits + height * widthbytes);//bmp文件长度  //构造Bitmap文件信息头BITMAPINFOHEADER bitmapInfoHeader.biBitCount = bitcount; bitmapInfoHeader.biClrImportant = 0; bitmapInfoHeader.biClrUsed = 0; bitmapInfoHeader.biCompression = BI_RGB; bitmapInfoHeader.biHeight = height; bitmapInfoHeader.biWidth = width; bitmapInfoHeader.biPlanes = 1; bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER); bitmapInfoHeader.biSizeImage = height * widthbytes; bitmapInfoHeader.biXPelsPerMeter = 3780; bitmapInfoHeader.biYPelsPerMeter = 3780; //创建BMP内存映像 BYTE* pMyBmp = new BYTE[bitmapFileHeader.bfSize];
BYTE* curr=pMyBmp ; memset(curr,0,bitmapFileHeader.bfSize); //写入头信息 memcpy(curr,&bitmapFileHeader,sizeof(BITMAPFILEHEADER));
curr=pMyBmp+sizeof(BITMAPFILEHEADER); memcpy(curr,&bitmapInfoHeader,sizeof(BITMAPINFOHEADER)); curr+=sizeof(BITMAPINFOHEADER);
//构造调色板  if(bitcount == 8) { rgbquad[3] = 0; for(i = 0; i < index; i++) { rgbquad[0] = rgbquad[1] = rgbquad[2] = i; memcpy(curr,rgbquad,sizeof(RGBQUAD)); curr+=sizeof(RGBQUAD); } }else if(bitcount == 1) { rgbquad[3] = 0; for(i = 0; i < index; i++) { rgbquad[0] = rgbquad[1] = rgbquad[2] = (256 - i)%256; memcpy(curr,rgbquad,sizeof(RGBQUAD)); curr+=sizeof(RGBQUAD); } } // 写入图像数据 memcpy(curr,pBits,height * widthbytes); cli::array<BYTE>^ bmpBytes2 =gcnew array<BYTE>(bitmapFileHeader.bfSize); pin_ptr<BYTE> p2 = &bmpBytes2[0]; ::memcpy(p2, pMyBmp, bmpBytes2->Length * sizeof(BYTE) );//将BMP的数据从非托管空间复制到托管空间 System::IO::MemoryStream^ ms2=gcnew System::IO::MemoryStream(bmpBytes2);//直接通过内存数据,创建内存数据流 Image image=Image::FromStream(ms2);//由数据流创建Image类对象

你可能感兴趣的:(bitmap)