/// <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)); this.configuration = image.GetConfiguration(); ImageMetadata metadata = image.Metadata; TgaMetadata tgaMetadata = metadata.GetFormatMetadata(TgaFormat.Instance); this.bitsPerPixel = this.bitsPerPixel ?? tgaMetadata.BitsPerPixel; TgaImageType imageType = this.compression is TgaCompression.RunLength ? TgaImageType.RleTrueColor : TgaImageType.TrueColor; if (this.bitsPerPixel == TgaBitsPerPixel.Pixel8) { imageType = this.compression is TgaCompression.RunLength ? TgaImageType.RleBlackAndWhite : TgaImageType.BlackAndWhite; } // If compression is used, set bit 5 of the image descriptor to indicate an left top origin. byte imageDescriptor = (byte)(this.compression is TgaCompression.RunLength ? 32 : 0); var fileHeader = new TgaFileHeader( idLength: 0, colorMapType: 0, imageType: imageType, cMapStart: 0, cMapLength: 0, cMapDepth: 0, xOffset: 0, yOffset: this.compression is TgaCompression.RunLength ? (short)image.Height : (short)0, // When run length encoding is used, the origin should be top left instead of the default bottom left. width: (short)image.Width, height: (short)image.Height, pixelDepth: (byte)this.bitsPerPixel.Value, imageDescriptor: imageDescriptor); #if NETCOREAPP2_1 Span <byte> buffer = stackalloc byte[TgaFileHeader.Size]; #else byte[] buffer = new byte[TgaFileHeader.Size]; #endif fileHeader.WriteTo(buffer); stream.Write(buffer, 0, TgaFileHeader.Size); if (this.compression is TgaCompression.RunLength) { this.WriteRunLengthEndcodedImage(stream, image.Frames.RootFrame); } else { 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 : unmanaged, IPixel <TPixel> { Guard.NotNull(image, nameof(image)); Guard.NotNull(stream, nameof(stream)); this.configuration = image.GetConfiguration(); ImageMetadata metadata = image.Metadata; TgaMetadata tgaMetadata = metadata.GetTgaMetadata(); this.bitsPerPixel = this.bitsPerPixel ?? tgaMetadata.BitsPerPixel; TgaImageType imageType = this.compression is TgaCompression.RunLength ? TgaImageType.RleTrueColor : TgaImageType.TrueColor; if (this.bitsPerPixel == TgaBitsPerPixel.Pixel8) { imageType = this.compression is TgaCompression.RunLength ? TgaImageType.RleBlackAndWhite : TgaImageType.BlackAndWhite; } byte imageDescriptor = 0; if (this.compression is TgaCompression.RunLength) { // If compression is used, set bit 5 of the image descriptor to indicate a left top origin. imageDescriptor |= 0x20; } if (this.bitsPerPixel is TgaBitsPerPixel.Pixel32) { // Indicate, that 8 bit are used for the alpha channel. imageDescriptor |= 0x8; } if (this.bitsPerPixel is TgaBitsPerPixel.Pixel16) { // Indicate, that 1 bit is used for the alpha channel. imageDescriptor |= 0x1; } var fileHeader = new TgaFileHeader( idLength: 0, colorMapType: 0, imageType: imageType, cMapStart: 0, cMapLength: 0, cMapDepth: 0, xOffset: 0, yOffset: this.compression is TgaCompression.RunLength ? (short)image.Height : (short)0, // When run length encoding is used, the origin should be top left instead of the default bottom left. width: (short)image.Width, height: (short)image.Height, pixelDepth: (byte)this.bitsPerPixel.Value, imageDescriptor: imageDescriptor); Span <byte> buffer = stackalloc byte[TgaFileHeader.Size]; fileHeader.WriteTo(buffer); stream.Write(buffer, 0, TgaFileHeader.Size); if (this.compression is TgaCompression.RunLength) { this.WriteRunLengthEncodedImage(stream, image.Frames.RootFrame); } else { this.WriteImage(stream, image.Frames.RootFrame); } stream.Flush(); }