using System; public class BitmapBytes { /// /// Converts RGBA bytes into an RGBA Bitmap. /// Pixels go left to right, bottom to top. /// Can write to file with, e.g: /// File.WriteAllBytes("example.bmp", BitmapBytes.FromRGBABytes(imageData, width)); /// /// array of r,g,b,a pixels, must be divisible by 4 /// the image width, in pixels, height is omitted as it gets calculated /// a byte array in bmp format public static byte[] FromRGBABytes(byte[] rgba, int width) { int height = (rgba.Length / 4) / width; var bytes = new byte[rgba.Length + bmpHeader.Length]; //write header Buffer.BlockCopy(bmpHeader, 0, bytes, 0, bmpHeader.Length); //write filesize to offset 2 Buffer.BlockCopy(BitConverter.GetBytes(bytes.Length), 0, bytes, 2, 4); //write width to offset 18 Buffer.BlockCopy(BitConverter.GetBytes(width), 0, bytes, 18, 4); //write height to offset 22 Buffer.BlockCopy(BitConverter.GetBytes(height), 0, bytes, 22, 4); //write image size to offset 34 Buffer.BlockCopy(BitConverter.GetBytes(width * height * 4), 0, bytes, 34, 4); //finally, write the image data Buffer.BlockCopy(rgba, 0, bytes, bmpHeader.Length, rgba.Length); return bytes; } static byte[] bmpHeader = new byte[] // All values are little-endian { 0x42, 0x4D, // Signature 'BM' 0xaa, 0x00, 0x00, 0x00, // Size: e.g. 170 bytes 0x00, 0x00, // Unused 0x00, 0x00, // Unused 0x8a, 0x00, 0x00, 0x00, // Offset to image data 0x7c, 0x00, 0x00, 0x00, // DIB header size (124 bytes) 0x04, 0x00, 0x00, 0x00, // Width (e.g. 4px) 0x02, 0x00, 0x00, 0x00, // Height (e.g. 2px) 0x01, 0x00, // Planes (1) 0x20, 0x00, // Bits per pixel (32) 0x03, 0x00, 0x00, 0x00, // Format (bitfield = use bitfields | no compression) 0x20, 0x00, 0x00, 0x00, // Image raw size (32 bytes) 0x13, 0x0B, 0x00, 0x00, // Horizontal print resolution (2835 = 72dpi * 39.3701) 0x13, 0x0B, 0x00, 0x00, // Vertical print resolution (2835 = 72dpi * 39.3701) 0x00, 0x00, 0x00, 0x00, // Colors in palette (none) 0x00, 0x00, 0x00, 0x00, // Important colors (0 = all) 0xFF, 0x00, 0x00, 0x00, // R bitmask (00FF0000) 0x00, 0xFF, 0x00, 0x00, // G bitmask (0000FF00) 0x00, 0x00, 0xFF, 0x00, // B bitmask (000000FF) 0x00, 0x00, 0x00, 0xFF, // A bitmask (FF000000) 0x42, 0x47, 0x52, 0x73, // sRGB color space 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Unused R, G, B entries for color space 0x00, 0x00, 0x00, 0x00, // Unused Gamma X entry for color space 0x00, 0x00, 0x00, 0x00, // Unused Gamma Y entry for color space 0x00, 0x00, 0x00, 0x00, // Unused Gamma Z entry for color space 0x00, 0x00, 0x00, 0x00, // Unknown 0x00, 0x00, 0x00, 0x00, // Unknown 0x00, 0x00, 0x00, 0x00, // Unknown 0x00, 0x00, 0x00, 0x00, // Unknown }; }