/// <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); }
/// <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); }
/// <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); }
/// <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)); }
/// <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) }; }
/// <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(); }
/// <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(); }
/// <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(); }
/// <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(); }