如何从C#中的byte []创建一个bmp文件

我在TCP Client中收到一个byte []数组.该数组包含一个24位RGB位图文件.如何使用给定的Width,Height和数据创建该位图文件

在C我用这个

int WriteBitmapFile(const char *filename,int width,int height,unsigned char *imageData)
{
FILE             *filePtr;        // file pointer
BITMAPFILEHEADER bitmapFileHeader;    // bitmap file header
BITMAPINFOHEADER bitmapInfoHeader;    // bitmap info header
DWORD                 imageIdx;    // used for swapping RGB->BGR
unsigned char     tempRGB;            // used for swapping

// open file for writing binary mode
filePtr = fopen(filename,"wb");
if (!filePtr)
    return 0;

// define the bitmap file header
bitmapFileHeader.bfSize = sizeof(BITMAPFILEHEADER);
bitmapFileHeader.bfType = 0x4D42;
bitmapFileHeader.bfReserved1 = 0;
bitmapFileHeader.bfReserved2 = 0;
bitmapFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

// define the bitmap information header
bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfoHeader.biPlanes = 1;
bitmapInfoHeader.biBitCount = 32;                        // 24-bit
bitmapInfoHeader.biCompression = BI_RGB;                // no compression
bitmapInfoHeader.biSizeImage = width * abs(height) * 4;    // width * height * (RGB bytes)
bitmapInfoHeader.biXPelsPerMeter = 0;
bitmapInfoHeader.biYPelsPerMeter = 0;
bitmapInfoHeader.biClrUsed = 0;
bitmapInfoHeader.biClrImportant = 0;
bitmapInfoHeader.biWidth = width;                        // bitmap width
bitmapInfoHeader.biHeight = height;                    // bitmap height

// switch the image data from RGB to BGR
for(imageIdx = 0; imageIdx < bitmapInfoHeader.biSizeImage; imageIdx+=4)
{
    tempRGB = imageData[imageIdx];
    imageData[imageIdx] = imageData[imageIdx + 2];
    imageData[imageIdx + 2] = tempRGB;
}

// write the bitmap file header
fwrite(&bitmapFileHeader,1,sizeof(BITMAPFILEHEADER),filePtr);

// write the bitmap info header
fwrite(&bitmapInfoHeader,sizeof(BITMAPINFOHEADER),filePtr);

// write the image data
fwrite(imageData,bitmapInfoHeader.biSizeImage,filePtr);

// close our file
fclose(filePtr);

// Success
return 1;
}

在C#中怎么做?

解决方法

如果数组实际上包含一个位图文件,那么你可以将这些字节保存为一个文件
File.WriteallBytes(fileName,imageData);

如果数组仅包含原始像素数据,则可以使用数据创建Bitmap对象:

unsafe {
   fixed (byte* ptr = imageData) {
      using (Bitmap image = new Bitmap(width,height,stride,PixelFormat.Format24bppRgb,new IntPtr(ptr))) {
         image.Save(fileName);
      }
   }
}

步幅值是扫描线之间的字节数.如果扫描线之间没有填充,则对于24bpp格式,它的宽度为* 3.

方法使用数组中的数据,而不会在内存中创建整个映像的另一个副本(这就是为什么需要stride值).

如果位图数据被颠倒存储在数组中,则步幅值应为负值,指针应为存储器中最后一行扫描行的开始位置(ptr stride *(height-1))).

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...