Come creare un file bmp dal byte in C #

Ho ricevuto un array byte [] nel client TCP. L’array contiene un file bitmap RGB a 24 bit. Come creare un file bitmap con larghezza, altezza e dati?

In C ++ lo uso

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, 1, sizeof(BITMAPINFOHEADER), filePtr); // write the image data fwrite(imageData, 1, bitmapInfoHeader.biSizeImage, filePtr); // close our file fclose(filePtr); // Success return 1; } 

Come potrei farlo in C #?

Se la matrice contiene effettivamente un file bitmap, puoi semplicemente salvare i byte come file:

 File.WriteAllBytes(fileName, imageData); 

Se la matrice contiene solo dati di pixel grezzi, puoi creare un object Bitmap usando i dati:

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

Il valore di stride è il numero di byte tra le linee di scansione. Se non ci sono padding tra le linee di scansione, è width * 3 per un formato a 24 bpp.

Questo metodo utilizza i dati nell’array senza creare un’altra copia dell’intera immagine in memoria (motivo per cui ha bisogno del valore di falcata).

Se i dati della bitmap vengono memorizzati al contrario nell’array, il valore della stride dovrebbe essere negativo e il puntatore dovrebbe essere l’inizio dell’ultima riga di scansione in memoria ( ptr + stride * (height - 1) ).

Non posso testarlo usando lo stream che riceverete, ma dovrebbe funzionare.

 int WriteBitmapFile(string filename, int width, int height, byte[] imageData) { using (var stream = new MemoryStream(imageData)) using (var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb)) { BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat); Marshal.Copy(imageData, 0, bmpData.Scan0, imageData.Length); bmp.UnlockBits(bmpData); bmp.Save(filename); } return 1; } 

Consiglierei di creare una bitmap in C # e di salvarla da sé.

Per un esempio, vedi questo post. (In particolare, l’ultima risposta è corretta.)

questo è un modo per farlo, qui ho creato un argomento Event personalizzato che contiene la dimensione in cui l’immagine è stata memorizzata come array di byte. Potresti non aver bisogno di preoccuparti di questo, questo è stato il codice che ho creato per recuperare le immagini da un array di byte che una telecamera Gige stava memorizzando in modo tale per me questo ha reso senso.

 public Bitmap ShowImage(byte[] sender, EventImageParams e) { Bitmap bitmap = new Bitmap(e.width, e.height, PixelFormat.Format24bppRgb); BitmapData bmData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); IntPtr pNative = bmData.Scan0; Marshal.Copy(sender, 0, pNative, (e.width * e.height * 3)); // bitmap.UnlockBits(bmData); return bitmap; }