예제 #1
0
 public EditableBitmap()
 {
     FileName     = "";
     Height       = 0;
     Width        = 0;
     RowSize      = 0;
     BitsPerPixel = 0;
     FileHeader   = new BitmapFileHeader();
     InfoHeader   = new DIBHeader();
 }
예제 #2
0
        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();
        }
예제 #3
0
        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();
        }