public EditableBitmap() { FileName = ""; Height = 0; Width = 0; RowSize = 0; BitsPerPixel = 0; FileHeader = new BitmapFileHeader(); InfoHeader = new DIBHeader(); }
public void SaveImage(string fileName) { var stream = new FileStream(fileName, FileMode.Create); var writer = new BinaryWriter(stream); InfoHeader = new DIBHeader { Size = (uint)DIBHeaderVersion.BITMAPINFOHEADER, Width = Width, Height = Height, Planes = 1, BitCount = 24, Compression = CompressionMethod.BI_RGB, SizeImage = (uint)(((Width * 3 + 3) & 0xFFFFFFFCu) * Height), XPelsPerMeter = 2835, YPelsPerMeter = 2835, ClrUsed = 0, ClrImportant = 0 }; FileHeader = new BitmapFileHeader { Size = 14 + InfoHeader.Size + InfoHeader.SizeImage, OffBits = 14 + InfoHeader.Size }; WriteFileHeader(writer); WriteDIBHeader(writer); int paddingSize = RowSize - (Width * BitsPerPixel) / 8; byte[] paddingData = { 0, 0, 0, 0 }; for (int i = Height - 1; i >= 0; i--) { for (int j = 0; j < Width; j++) { var cur = GetPixelRowColumn(i, j); writer.Write(cur.B); writer.Write(cur.G); writer.Write(cur.R); } writer.Write(paddingData, 0, paddingSize); } writer.Close(); stream.Close(); }
private void LoadBitmap() { MemoryStream memoryStream = new MemoryStream(File.ReadAllBytes(FileName)); var reader = new BinaryReader(memoryStream); // read Bitmap file header FileHeader = new BitmapFileHeader(); ReadFileHeader(reader); // read DIB header InfoHeader = new DIBHeader(); ReadDIBHeader(reader); Height = InfoHeader.Height; Width = InfoHeader.Width; BitsPerPixel = InfoHeader.BitCount; CalcRowSize(); // (in bytes), in addition to padding if (InfoHeader.Compression != CompressionMethod.BI_RGB && InfoHeader.Compression != CompressionMethod.BI_RLE4 && InfoHeader.Compression != CompressionMethod.BI_RLE8 && InfoHeader.Compression != CompressionMethod.BI_BITFIELDS) { throw new Exception("Unsupprted format: " + InfoHeader.Compression); } // read Extra bit masks // 8.8.8.0 BMask = 0x000000FF; GMask = 0x0000FF00; RMask = 0x00FF0000; if (BitsPerPixel == 16) { //5.5.5.0 BMask = 0x001F; GMask = 0x03E0; RMask = 0x7C00; } if (InfoHeader.Size == (uint)DIBHeaderVersion.BITMAPV4HEADER || InfoHeader.Size == (uint)DIBHeaderVersion.BITMAPV5HEADER) { BMask = InfoHeader.BlueMask; GMask = InfoHeader.GreenMask; RMask = InfoHeader.RedMask; } if (InfoHeader.Compression == CompressionMethod.BI_BITFIELDS) { RMask = reader.ReadUInt32(); GMask = reader.ReadUInt32(); BMask = reader.ReadUInt32(); } // it's illegal to combine 1/4/8/24bpp with BI_BITFIELDS or with BITMAPV4HEADER or BITMAPV5HEADER, so I'll ignore the colors bit masks if (BitsPerPixel != 16 || BitsPerPixel != 32) { // default colors bit masks for 24bpp BMask = 0x000000FF; GMask = 0x0000FF00; RMask = 0x00FF0000; } // Top-down DIBs cannot be compressed if (Height < 0 && (InfoHeader.Compression != CompressionMethod.BI_RGB || InfoHeader.Compression != CompressionMethod.BI_BITFIELDS)) { throw new Exception("Top-down DIBs can't be compressed. DIBHeader.Compression=" + InfoHeader.Compression); } if (BitsPerPixel <= 8 || InfoHeader.ClrUsed > 0) { ReadPalette(reader); } else { Palette = null; } SeekToPixelArray(reader); if (BitsPerPixel == 32) { Read32bitBitmap(memoryStream, Height < 0); } else if (BitsPerPixel == 24) { Read24bitBitmap(memoryStream, Height < 0); } else if (BitsPerPixel == 16) { Read16bitBitmap(memoryStream, Height < 0); } else if (BitsPerPixel == 8) { if (InfoHeader.Compression == CompressionMethod.BI_RLE4) { ReadRLE4Bitmap(reader); } else if (InfoHeader.Compression == CompressionMethod.BI_RLE8) { ReadRLE8Bitmap(reader); } else { ReadIndexedBitmap(memoryStream, Height < 0); } } // no need to keep it negative, in case it is Height = Math.Abs(Height); memoryStream.Dispose(); reader.Dispose(); }