Browse Source

Add PngTransparentColorBehavior enum

pull/1012/head
Brian Popow 6 years ago
parent
commit
ec3656ff7a
  1. 5
      src/ImageSharp/Formats/Png/IPngEncoderOptions.cs
  2. 2
      src/ImageSharp/Formats/Png/PngEncoder.cs
  3. 15
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  4. 4
      src/ImageSharp/Formats/Png/PngEncoderOptions.cs
  5. 22
      src/ImageSharp/Formats/Png/PngTransparentColorBehavior.cs
  6. 8
      tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs

5
src/ImageSharp/Formats/Png/IPngEncoderOptions.cs

@ -70,8 +70,9 @@ namespace SixLabors.ImageSharp.Formats.Png
PngChunkFilter? ChunkFilter { get; }
/// <summary>
/// Gets a value indicating whether fully transparent pixels should be converted to black pixels.
/// Gets a value indicating whether fully transparent pixels that may contain R, G, B values which are not 0,
/// should be converted to transparent black, which can yield in better compression in some cases.
/// </summary>
bool MakeTransparentBlack { get; }
PngTransparentColorBehavior TransparentColorBehavior { get; }
}
}

2
src/ImageSharp/Formats/Png/PngEncoder.cs

@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Formats.Png
public bool IgnoreMetadata { get; set; }
/// <inheritdoc/>
public bool MakeTransparentBlack { get; set; }
public PngTransparentColorBehavior TransparentColorBehavior { get; set; }
/// <summary>
/// Encodes the image to the specified stream from the <see cref="Image{TPixel}"/>.

15
src/ImageSharp/Formats/Png/PngEncoderCore.cs

@ -145,10 +145,11 @@ namespace SixLabors.ImageSharp.Formats.Png
PngMetadata pngMetadata = metadata.GetFormatMetadata(PngFormat.Instance);
PngEncoderOptionsHelpers.AdjustOptions<TPixel>(this.options, pngMetadata, out this.use16Bit, out this.bytesPerPixel);
Image<TPixel> clonedImage = null;
if (this.options.MakeTransparentBlack)
bool clearTransparency = this.options.TransparentColorBehavior == PngTransparentColorBehavior.Clear;
if (clearTransparency)
{
clonedImage = image.Clone();
MakeTransparentPixelsBlack(clonedImage);
ClearTransparentPixels(clonedImage);
}
IndexedImageFrame<TPixel> quantized = this.CreateQuantizedImage(image, clonedImage);
@ -162,7 +163,7 @@ namespace SixLabors.ImageSharp.Formats.Png
this.WritePhysicalChunk(stream, metadata);
this.WriteExifChunk(stream, metadata);
this.WriteTextChunks(stream, pngMetadata);
this.WriteDataChunks(this.options.MakeTransparentBlack ? clonedImage : image, quantized, stream);
this.WriteDataChunks(clearTransparency ? clonedImage : image, quantized, stream);
this.WriteEndChunk(stream);
stream.Flush();
@ -190,11 +191,11 @@ namespace SixLabors.ImageSharp.Formats.Png
}
/// <summary>
/// Makes transparent pixels black.
/// Convert transparent pixels, to transparent black pixels, which can yield to better compression in some cases.
/// </summary>
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
/// <param name="image">The cloned image where the transparent pixels will be changed.</param>
private static void MakeTransparentPixelsBlack<TPixel>(Image<TPixel> image)
private static void ClearTransparentPixels<TPixel>(Image<TPixel> image)
where TPixel : unmanaged, IPixel<TPixel>
{
Rgba32 rgba32 = default;
@ -207,7 +208,7 @@ namespace SixLabors.ImageSharp.Formats.Png
if (rgba32.A == 0)
{
span[x].FromRgba32(Color.Black);
span[x].FromRgba32(Color.Transparent);
}
}
}
@ -224,7 +225,7 @@ namespace SixLabors.ImageSharp.Formats.Png
where TPixel : unmanaged, IPixel<TPixel>
{
IndexedImageFrame<TPixel> quantized;
if (this.options.MakeTransparentBlack)
if (this.options.TransparentColorBehavior == PngTransparentColorBehavior.Clear)
{
quantized = PngEncoderOptionsHelpers.CreateQuantizedFrame(this.options, clonedImage);
this.bitDepth = PngEncoderOptionsHelpers.CalculateBitDepth(this.options, quantized);

4
src/ImageSharp/Formats/Png/PngEncoderOptions.cs

@ -31,7 +31,7 @@ namespace SixLabors.ImageSharp.Formats.Png
this.InterlaceMethod = source.InterlaceMethod;
this.ChunkFilter = source.ChunkFilter;
this.IgnoreMetadata = source.IgnoreMetadata;
this.MakeTransparentBlack = source.MakeTransparentBlack;
this.TransparentColorBehavior = source.TransparentColorBehavior;
}
/// <inheritdoc/>
@ -68,6 +68,6 @@ namespace SixLabors.ImageSharp.Formats.Png
public bool IgnoreMetadata { get; set; }
/// <inheritdoc/>
public bool MakeTransparentBlack { get; set; }
public PngTransparentColorBehavior TransparentColorBehavior { get; set; }
}
}

22
src/ImageSharp/Formats/Png/PngTransparentColorBehavior.cs

@ -0,0 +1,22 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the GNU Affero General Public License, Version 3.
namespace SixLabors.ImageSharp.Formats.Png
{
/// <summary>
/// Enum indicating how the transparency should be handled on encoding.
/// </summary>
public enum PngTransparentColorBehavior
{
/// <summary>
/// Converts fully transparent pixels that may contain R, G, B values which are not 0,
/// to transparent black, which can yield in better compression in some cases.
/// </summary>
Clear,
/// <summary>
/// The transparency will be kept as is.
/// </summary>
Preserve
}
}

8
tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs

@ -392,17 +392,15 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
[Theory]
[InlineData(PngColorType.Palette)]
[InlineData(PngColorType.Rgb)]
[InlineData(PngColorType.RgbWithAlpha)]
[InlineData(PngColorType.Grayscale)]
[InlineData(PngColorType.GrayscaleWithAlpha)]
public void Encode_WithMakeTransparentBlackOption_Works(PngColorType colorType)
public void Encode_WithPngTransparentColorBehaviorClear_Works(PngColorType colorType)
{
// arrange
var image = new Image<Rgba32>(50, 50);
var encoder = new PngEncoder()
{
MakeTransparentBlack = true,
TransparentColorBehavior = PngTransparentColorBehavior.Clear,
ColorType = colorType
};
Rgba32 rgba32 = Color.Blue;
@ -442,7 +440,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
if (y > 25)
{
expectedColor = Color.Black;
expectedColor = Color.Transparent;
}
for (int x = 0; x < actual.Width; x++)

Loading…
Cancel
Save