diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 09575bb288..efe0f20694 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -146,7 +146,7 @@ namespace SixLabors.ImageSharp.Formats.Png ImageMetadata metadata = image.Metadata; PngMetadata pngMetadata = metadata.GetFormatMetadata(PngFormat.Instance); - PngEncoderOptionsHelpers.AdjustOptions(this.options, pngMetadata, out this.use16Bit, out this.bytesPerPixel); + PngEncoderOptionsHelpers.AdjustOptions(this.options, pngMetadata, out this.use16Bit, out this.bytesPerPixel); IQuantizedFrame quantized = PngEncoderOptionsHelpers.CreateQuantizedFrame(this.options, image); this.bitDepth = PngEncoderOptionsHelpers.CalculateBitDepth(this.options, image, quantized); diff --git a/src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs b/src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs index e3f2948864..1b6330a3c8 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs @@ -20,16 +20,19 @@ namespace SixLabors.ImageSharp.Formats.Png /// The PNG metadata. /// if set to true [use16 bit]. /// The bytes per pixel. - public static void AdjustOptions( + public static void AdjustOptions( PngEncoderOptions options, PngMetadata pngMetadata, out bool use16Bit, out int bytesPerPixel) + where TPixel : struct, IPixel { // Always take the encoder options over the metadata values. options.Gamma = options.Gamma ?? pngMetadata.Gamma; - options.ColorType = options.ColorType ?? pngMetadata.ColorType; - options.BitDepth = options.BitDepth ?? pngMetadata.BitDepth; + + options.ColorType = options.ColorType ?? SuggestColorType() ?? pngMetadata.ColorType; + options.BitDepth = options.BitDepth ?? SuggestBitDepth() ?? pngMetadata.BitDepth; + options.InterlaceMethod = options.InterlaceMethod ?? pngMetadata.InterlaceMethod; use16Bit = options.BitDepth == PngBitDepth.Bit16; @@ -148,5 +151,71 @@ namespace SixLabors.ImageSharp.Formats.Png return use16Bit ? 8 : 4; } } + + /// + /// Comes up with the appropriate PngColorType for some kinds of + /// IPixel. This is not exhaustive because not all options have + /// reasonable defaults + /// + private static PngColorType? SuggestColorType() + where TPixel : struct, IPixel + { + Type tPixel = typeof(TPixel); + + if (tPixel == typeof(Alpha8)) + { + return PngColorType.GrayscaleWithAlpha; + } + if (tPixel == typeof(Argb32)) + { + return PngColorType.RgbWithAlpha; + } + if (tPixel == typeof(Rgb24)) + { + return PngColorType.Rgb; + } + if (tPixel == typeof(Gray16)) + { + return PngColorType.Grayscale; + } + if (tPixel == typeof(Gray8)) + { + return PngColorType.Grayscale; + } + return default; + } + + /// + /// Comes up with the appropriate PngBitDepth for some kinds of + /// IPixel. This is not exhaustive because not all options have + /// reasonable defaults + /// + private static PngBitDepth? SuggestBitDepth() + where TPixel : struct, IPixel + { + Type tPixel = typeof(TPixel); + + if (tPixel == typeof(Alpha8)) + { + return PngBitDepth.Bit8; + } + if (tPixel == typeof(Argb32)) + { + return PngBitDepth.Bit8; + } + if (tPixel == typeof(Rgb24)) + { + return PngBitDepth.Bit8; + } + if (tPixel == typeof(Gray16)) + { + return PngBitDepth.Bit16; + } + if (tPixel == typeof(Gray8)) + { + return PngBitDepth.Bit8; + } + return default; + } } }