如何从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))).

相关文章

在项目中使用SharpZipLib压缩文件夹的时候,遇到如果目录较深,则压缩包中的文件夹同样比较深的问题。比...
项目需要,几十万张照片需要计算出每个照片的特征值(调用C++编写的DLL)。 业务流程:选择照片...
var array = new byte[4]; var i = Encoding.UTF8.GetBytes(100.ToString(&quot;x2&quot;));//...
其实很简单,因为Combox的Item是一个K/V的object,那么就可以把它的items转换成IEnumerable&lt;Dic...
把.net4.6安装包打包进安装程序。 关键脚本如下: 头部引用字符串对比库 !include &quot;WordFunc....
项目需求(Winform)可以批量打印某个模板,经过百度和摸索,使用iTextSharp+ZXing.NetʿreeSp...