public void ToFile(string fileName) { BITMAPFILEHEADER bmfh; bmfh.bfType = 0x4D42; int fileSize = Marshal.SizeOf(typeof(BITMAPFILEHEADER)); fileSize += Marshal.SizeOf(typeof(BITMAPINFOHEADER)); fileSize += Marshal.SizeOf(typeof(RGBQUAD)) * colorTable.Count(); bmfh.bfOffBits = (uint)fileSize; fileSize += imageData.Count(); bmfh.bfSize = (uint)fileSize; bmfh.bfReserved1 = 0; bmfh.bfReserved2 = 0; using (var writer = new BinaryWriter(File.Open(fileName, FileMode.Create))) { ReadWriteStructWithAllocGCHandle.WriteTo <BITMAPFILEHEADER>(writer, bmfh); ReadWriteStructWithAllocGCHandle.WriteTo <BITMAPINFOHEADER>(writer, bmih); foreach (var c in colorTable) { ReadWriteStructWithAllocGCHandle.WriteTo <RGBQUAD>(writer, c); } writer.Write(imageData); } }
public static Bmp FromFile(string fileName) { Bmp bmp = new Bmp(); using (BinaryReader reader = new BinaryReader(File.Open(fileName, FileMode.Open))) { BITMAPFILEHEADER bmfh; bmfh = ReadWriteStructWithAllocGCHandle.ReadFrom <BITMAPFILEHEADER>(reader); if (bmfh.bfType != 0x4D42) { throw new FileFormatException(); } bmp.bmih = ReadWriteStructWithAllocGCHandle.ReadFrom <BITMAPINFOHEADER>(reader); uint numQuads; if (bmp.bmih.biClrUsed == 0) { switch (bmp.bmih.biBitCount) { case 1: case 4: case 8: numQuads = (uint)(1 << bmp.bmih.biBitCount); break; default: throw new FileFormatException(); } } else { numQuads = bmp.bmih.biClrUsed; } if (bmp.bmih.biHeight < 0) { // TODO: TopDown 形式のサポート throw new NotImplementedException(); } bmp.colorTable = new RGBQUAD[numQuads]; for (int i = 0; i < numQuads; ++i) { bmp.colorTable[i] = ReadWriteStructWithAllocGCHandle.ReadFrom <RGBQUAD>(reader); } if (reader.BaseStream.Position != bmfh.bfOffBits) { throw new FileFormatException(); } // https://stackoverflow.com/a/10038017/4699324 using (var ms = new MemoryStream()) { reader.BaseStream.CopyTo(ms); bmp.imageData = ms.ToArray(); } } return(bmp); } // FromFile