Пример #1
0
 /// <summary>
 /// Writes the bitmap header data to the binary stream.
 /// </summary>
 /// <param name="writer">
 /// The <see cref="EndianBinaryWriter"/> containing the stream to write to.
 /// </param>
 /// <param name="fileHeader">
 /// The <see cref="BmpFileHeader"/> containing the header data.
 /// </param>
 private static void WriteHeader(EndianBinaryWriter writer, BmpFileHeader fileHeader)
 {
     writer.Write(fileHeader.Type);
     writer.Write(fileHeader.FileSize);
     writer.Write(fileHeader.Reserved);
     writer.Write(fileHeader.Offset);
 }
Пример #2
0
        /// <summary>
        /// Reads the <see cref="BmpFileHeader"/> from the stream.
        /// </summary>
        private void ReadFileHeader()
        {
            byte[] buffer = new byte[BmpFileHeader.Size];

            this.stream.Read(buffer, 0, BmpFileHeader.Size);

            this.fileHeader = BmpFileHeader.Parse(buffer);
        }
Пример #3
0
        /// <summary>
        /// Reads the <see cref="BmpFileHeader"/> from the stream.
        /// </summary>
        private void ReadFileHeader()
        {
#if NETCOREAPP2_1
            Span <byte> buffer = stackalloc byte[BmpFileHeader.Size];
#else
            byte[] buffer = new byte[BmpFileHeader.Size];
#endif
            this.stream.Read(buffer, 0, BmpFileHeader.Size);

            this.fileHeader = BmpFileHeader.Parse(buffer);
        }
Пример #4
0
        /// <summary>
        /// Reads the <see cref="BmpFileHeader"/> from the stream.
        /// </summary>
        private void ReadFileHeader()
        {
            byte[] data = new byte[BmpFileHeader.Size];

            this.currentStream.Read(data, 0, BmpFileHeader.Size);

            this.fileHeader = new BmpFileHeader(
                type: BitConverter.ToInt16(data, 0),
                fileSize: BitConverter.ToInt32(data, 2),
                reserved: BitConverter.ToInt32(data, 6),
                offset: BitConverter.ToInt32(data, 10));
        }
Пример #5
0
        /// <summary>
        /// Reads the <see cref="BmpFileHeader"/> from the stream.
        /// </summary>
        private void ReadFileHeader()
        {
            byte[] data = new byte[BmpFileHeader.Size];

            this.currentStream.Read(data, 0, BmpFileHeader.Size);

            this.fileHeader = new BmpFileHeader
            {
                Type     = BitConverter.ToInt16(data, 0),
                FileSize = BitConverter.ToInt32(data, 2),
                Reserved = BitConverter.ToInt32(data, 6),
                Offset   = BitConverter.ToInt32(data, 10)
            };
        }
Пример #6
0
        /// <summary>
        /// Encodes the image to the specified stream from the <see cref="ImageFrame{TPixel}"/>.
        /// </summary>
        /// <typeparam name="TPixel">The pixel format.</typeparam>
        /// <param name="image">The <see cref="ImageFrame{TPixel}"/> to encode from.</param>
        /// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param>
        public void Encode <TPixel>(Image <TPixel> image, Stream stream)
            where TPixel : struct, IPixel <TPixel>
        {
            Guard.NotNull(image, nameof(image));
            Guard.NotNull(stream, nameof(stream));

            // Cast to int will get the bytes per pixel
            short bpp          = (short)(8 * (int)this.bitsPerPixel);
            int   bytesPerLine = 4 * (((image.Width * bpp) + 31) / 32);

            this.padding = bytesPerLine - (image.Width * (int)this.bitsPerPixel);

            var infoHeader = new BmpInfoHeader(
                headerSize: BmpInfoHeader.Size,
                height: image.Height,
                width: image.Width,
                bitsPerPixel: bpp,
                planes: 1,
                imageSize: image.Height * bytesPerLine,
                clrUsed: 0,
                clrImportant: 0);

            var fileHeader = new BmpFileHeader(
                type: 19778, // BM
                offset: 54,
                reserved: 0,
                fileSize: 54 + infoHeader.ImageSize);

#if NETCOREAPP2_1
            Span <byte> buffer = stackalloc byte[40];
#else
            byte[] buffer = new byte[40];
#endif
            fileHeader.WriteTo(buffer);

            stream.Write(buffer, 0, BmpFileHeader.Size);

            infoHeader.WriteTo(buffer);

            stream.Write(buffer, 0, 40);

            this.WriteImage(stream, image.Frames.RootFrame);

            stream.Flush();
        }
Пример #7
0
        /// <summary>
        /// Encodes the image to the specified stream from the <see cref="ImageFrame{TPixel}"/>.
        /// </summary>
        /// <typeparam name="TPixel">The pixel format.</typeparam>
        /// <param name="image">The <see cref="ImageFrame{TPixel}"/> to encode from.</param>
        /// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param>
        public void Encode <TPixel>(Image <TPixel> image, Stream stream)
            where TPixel : struct, IPixel <TPixel>
        {
            Guard.NotNull(image, nameof(image));
            Guard.NotNull(stream, nameof(stream));

            // Cast to int will get the bytes per pixel
            short bpp          = (short)(8 * (int)this.bitsPerPixel);
            int   bytesPerLine = 4 * (((image.Width * bpp) + 31) / 32);

            this.padding = bytesPerLine - (image.Width * (int)this.bitsPerPixel);

            // Do not use IDisposable pattern here as we want to preserve the stream.
            var writer = new EndianBinaryWriter(Endianness.LittleEndian, stream);

            var infoHeader = new BmpInfoHeader
            {
                HeaderSize   = sizeof(uint),
                Height       = image.Height,
                Width        = image.Width,
                BitsPerPixel = (ushort)bpp,
                Planes       = 1,
                ImageSize    = (uint)(image.Height * bytesPerLine),
                ClrUsed      = 0,
                ClrImportant = 0
            };

            uint offset     = (uint)(BmpFileHeader.Size + infoHeader.HeaderSize);
            var  fileHeader = new BmpFileHeader
            {
                Type      = 0x4D42, // BM
                FileSize  = offset + (uint)infoHeader.ImageSize,
                Reserved1 = 0,
                Reserved2 = 0,
                Offset    = offset
            };

            WriteHeader(writer, fileHeader);
            this.WriteInfo(writer, infoHeader);
            this.WriteImage(writer, image.Frames.RootFrame);

            writer.Flush();
        }
Пример #8
0
        /// <summary>
        /// Encodes the image to the specified stream from the <see cref="ImageFrame{TPixel}"/>.
        /// </summary>
        /// <typeparam name="TPixel">The pixel format.</typeparam>
        /// <param name="image">The <see cref="ImageFrame{TPixel}"/> to encode from.</param>
        /// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param>
        public void Encode <TPixel>(Image <TPixel> image, Stream stream)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            Guard.NotNull(image, nameof(image));
            Guard.NotNull(stream, nameof(stream));

            this.configuration = image.GetConfiguration();
            ImageMetadata metadata    = image.Metadata;
            BmpMetadata   bmpMetadata = metadata.GetBmpMetadata();

            this.bitsPerPixel = this.bitsPerPixel ?? bmpMetadata.BitsPerPixel;

            short bpp          = (short)this.bitsPerPixel;
            int   bytesPerLine = 4 * (((image.Width * bpp) + 31) / 32);

            this.padding = bytesPerLine - (int)(image.Width * (bpp / 8F));

            // Set Resolution.
            int hResolution = 0;
            int vResolution = 0;

            if (metadata.ResolutionUnits != PixelResolutionUnit.AspectRatio)
            {
                if (metadata.HorizontalResolution > 0 && metadata.VerticalResolution > 0)
                {
                    switch (metadata.ResolutionUnits)
                    {
                    case PixelResolutionUnit.PixelsPerInch:

                        hResolution = (int)Math.Round(UnitConverter.InchToMeter(metadata.HorizontalResolution));
                        vResolution = (int)Math.Round(UnitConverter.InchToMeter(metadata.VerticalResolution));
                        break;

                    case PixelResolutionUnit.PixelsPerCentimeter:

                        hResolution = (int)Math.Round(UnitConverter.CmToMeter(metadata.HorizontalResolution));
                        vResolution = (int)Math.Round(UnitConverter.CmToMeter(metadata.VerticalResolution));
                        break;

                    case PixelResolutionUnit.PixelsPerMeter:
                        hResolution = (int)Math.Round(metadata.HorizontalResolution);
                        vResolution = (int)Math.Round(metadata.VerticalResolution);

                        break;
                    }
                }
            }

            int infoHeaderSize = this.writeV4Header ? BmpInfoHeader.SizeV4 : BmpInfoHeader.SizeV3;
            var infoHeader     = new BmpInfoHeader(
                headerSize: infoHeaderSize,
                height: image.Height,
                width: image.Width,
                bitsPerPixel: bpp,
                planes: 1,
                imageSize: image.Height * bytesPerLine,
                clrUsed: 0,
                clrImportant: 0,
                xPelsPerMeter: hResolution,
                yPelsPerMeter: vResolution);

            if (this.writeV4Header && this.bitsPerPixel == BmpBitsPerPixel.Pixel32)
            {
                infoHeader.AlphaMask   = Rgba32AlphaMask;
                infoHeader.RedMask     = Rgba32RedMask;
                infoHeader.GreenMask   = Rgba32GreenMask;
                infoHeader.BlueMask    = Rgba32BlueMask;
                infoHeader.Compression = BmpCompression.BitFields;
            }

            int colorPaletteSize = this.bitsPerPixel == BmpBitsPerPixel.Pixel8 ? ColorPaletteSize8Bit : 0;

            var fileHeader = new BmpFileHeader(
                type: BmpConstants.TypeMarkers.Bitmap,
                fileSize: BmpFileHeader.Size + infoHeaderSize + infoHeader.ImageSize,
                reserved: 0,
                offset: BmpFileHeader.Size + infoHeaderSize + colorPaletteSize);

            Span <byte> buffer = stackalloc byte[infoHeaderSize];

            fileHeader.WriteTo(buffer);

            stream.Write(buffer, 0, BmpFileHeader.Size);

            if (this.writeV4Header)
            {
                infoHeader.WriteV4Header(buffer);
            }
            else
            {
                infoHeader.WriteV3Header(buffer);
            }

            stream.Write(buffer, 0, infoHeaderSize);

            this.WriteImage(stream, image.Frames.RootFrame);

            stream.Flush();
        }
Пример #9
0
        /// <summary>
        /// Encodes the image to the specified stream from the <see cref="ImageFrame{TPixel}"/>.
        /// </summary>
        /// <typeparam name="TPixel">The pixel format.</typeparam>
        /// <param name="image">The <see cref="ImageFrame{TPixel}"/> to encode from.</param>
        /// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param>
        public void Encode <TPixel>(Image <TPixel> image, Stream stream)
            where TPixel : struct, IPixel <TPixel>
        {
            Guard.NotNull(image, nameof(image));
            Guard.NotNull(stream, nameof(stream));

            // Cast to int will get the bytes per pixel
            short bpp          = (short)(8 * (int)this.bitsPerPixel);
            int   bytesPerLine = 4 * (((image.Width * bpp) + 31) / 32);

            this.padding = bytesPerLine - (image.Width * (int)this.bitsPerPixel);

            // Set Resolution.
            ImageMetaData meta        = image.MetaData;
            int           hResolution = 0;
            int           vResolution = 0;

            if (meta.ResolutionUnits != PixelResolutionUnit.AspectRatio)
            {
                if (meta.HorizontalResolution > 0 && meta.VerticalResolution > 0)
                {
                    switch (meta.ResolutionUnits)
                    {
                    case PixelResolutionUnit.PixelsPerInch:

                        hResolution = (int)Math.Round(UnitConverter.InchToMeter(meta.HorizontalResolution));
                        vResolution = (int)Math.Round(UnitConverter.InchToMeter(meta.VerticalResolution));
                        break;

                    case PixelResolutionUnit.PixelsPerCentimeter:

                        hResolution = (int)Math.Round(UnitConverter.CmToMeter(meta.HorizontalResolution));
                        vResolution = (int)Math.Round(UnitConverter.CmToMeter(meta.VerticalResolution));
                        break;

                    case PixelResolutionUnit.PixelsPerMeter:
                        hResolution = (int)Math.Round(meta.HorizontalResolution);
                        vResolution = (int)Math.Round(meta.VerticalResolution);

                        break;
                    }
                }
            }

            var infoHeader = new BmpInfoHeader(
                headerSize: BmpInfoHeader.Size,
                height: image.Height,
                width: image.Width,
                bitsPerPixel: bpp,
                planes: 1,
                imageSize: image.Height * bytesPerLine,
                clrUsed: 0,
                clrImportant: 0,
                xPelsPerMeter: hResolution,
                yPelsPerMeter: vResolution);

            var fileHeader = new BmpFileHeader(
                type: 19778, // BM
                offset: 54,
                reserved: 0,
                fileSize: 54 + infoHeader.ImageSize);

#if NETCOREAPP2_1
            Span <byte> buffer = stackalloc byte[40];
#else
            byte[] buffer = new byte[40];
#endif
            fileHeader.WriteTo(buffer);

            stream.Write(buffer, 0, BmpFileHeader.Size);

            infoHeader.WriteTo(buffer);

            stream.Write(buffer, 0, 40);

            this.WriteImage(stream, image.Frames.RootFrame);

            stream.Flush();
        }