我在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))).