Browse Source

Update: expanded optimize options

pull/1574/head
Peter Tribe 7 years ago
parent
commit
45f07ce484
  1. 4
      src/ImageSharp/Formats/Png/IPngEncoderOptions.cs
  2. 4
      src/ImageSharp/Formats/Png/PngEncoder.cs
  3. 37
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  4. 6
      src/ImageSharp/Formats/Png/PngEncoderOptions.cs
  5. 49
      src/ImageSharp/Formats/Png/PngOptimizeMethod.cs

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

@ -59,8 +59,8 @@ namespace SixLabors.ImageSharp.Formats.Png
PngInterlaceMode? InterlaceMethod { get; }
/// <summary>
/// Gets a value indicating whether this instance should skip certain chunks to decrease file size
/// Gets the optimize method.
/// </summary>
bool Optimized { get; }
PngOptimizeMethod? OptimizeMethod { get; }
}
}

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

@ -63,9 +63,9 @@ namespace SixLabors.ImageSharp.Formats.Png
public PngInterlaceMode? InterlaceMethod { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance should skip certain chunks to decrease file size
/// Gets or sets the optimize method.
/// </summary>
public bool Optimized { get; set; }
public PngOptimizeMethod? OptimizeMethod { get; set; }
/// <summary>
/// Encodes the image to the specified stream from the <see cref="Image{TPixel}"/>.

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

@ -153,14 +153,26 @@ namespace SixLabors.ImageSharp.Formats.Png
stream.Write(PngConstants.HeaderBytes, 0, PngConstants.HeaderBytes.Length);
this.WriteHeaderChunk(stream);
this.WritePaletteChunk(stream, quantized, this.options.Optimized);
this.WritePaletteChunk(stream, quantized, this.options.OptimizeMethod);
this.WriteTransparencyChunk(stream, pngMetadata);
if (!this.options.Optimized)
if (((this.options.OptimizeMethod ?? PngOptimizeMethod.None) & PngOptimizeMethod.SuppressPhysicalChunk) != PngOptimizeMethod.SuppressPhysicalChunk)
{
this.WritePhysicalChunk(stream, metadata);
}
if (((this.options.OptimizeMethod ?? PngOptimizeMethod.None) & PngOptimizeMethod.SuppressGammaChunk) != PngOptimizeMethod.SuppressGammaChunk)
{
this.WriteGammaChunk(stream);
}
if (((this.options.OptimizeMethod ?? PngOptimizeMethod.None) & PngOptimizeMethod.SuppressExifChunk) != PngOptimizeMethod.SuppressExifChunk)
{
this.WriteExifChunk(stream, metadata);
}
if (((this.options.OptimizeMethod ?? PngOptimizeMethod.None) & PngOptimizeMethod.SuppressTextChunks) != PngOptimizeMethod.SuppressTextChunks)
{
this.WriteTextChunks(stream, pngMetadata);
}
@ -552,8 +564,8 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
/// <param name="quantized">The quantized frame.</param>
/// <param name="optimized">If optimized make fully transparent pixels black.</param>
private void WritePaletteChunk<TPixel>(Stream stream, IQuantizedFrame<TPixel> quantized, bool optimized)
/// <param name="optimizeMethod">The optimize method.</param>
private void WritePaletteChunk<TPixel>(Stream stream, IQuantizedFrame<TPixel> quantized, PngOptimizeMethod? optimizeMethod)
where TPixel : struct, IPixel<TPixel>
{
if (quantized == null)
@ -576,6 +588,8 @@ namespace SixLabors.ImageSharp.Formats.Png
Rgba32 rgba = default;
bool makeTransparentBlack = ((optimizeMethod ?? PngOptimizeMethod.None) & PngOptimizeMethod.MakeTransparentBlack) == PngOptimizeMethod.MakeTransparentBlack;
for (int i = 0; i < paletteLength; i++)
{
if (quantizedSpan.IndexOf((byte)i) > -1)
@ -585,9 +599,18 @@ namespace SixLabors.ImageSharp.Formats.Png
byte alpha = rgba.A;
Unsafe.Add(ref colorTableRef, offset) = optimized && alpha == 0 ? (byte)0 : rgba.R;
Unsafe.Add(ref colorTableRef, offset + 1) = optimized && alpha == 0 ? (byte)0 : rgba.G;
Unsafe.Add(ref colorTableRef, offset + 2) = optimized && alpha == 0 ? (byte)0 : rgba.B;
if (makeTransparentBlack && alpha == 0)
{
Unsafe.Add(ref colorTableRef, offset) = 0;
Unsafe.Add(ref colorTableRef, offset + 1) = 0;
Unsafe.Add(ref colorTableRef, offset + 2) = 0;
}
else
{
Unsafe.Add(ref colorTableRef, offset) = rgba.R;
Unsafe.Add(ref colorTableRef, offset + 1) = rgba.G;
Unsafe.Add(ref colorTableRef, offset + 2) = rgba.B;
}
if (alpha > this.options.Threshold)
{

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

@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Formats.Png
this.Quantizer = source.Quantizer;
this.Threshold = source.Threshold;
this.InterlaceMethod = source.InterlaceMethod;
this.Optimized = source.Optimized;
this.OptimizeMethod = source.OptimizeMethod;
}
/// <summary>
@ -81,8 +81,8 @@ namespace SixLabors.ImageSharp.Formats.Png
public PngInterlaceMode? InterlaceMethod { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance should skip certain chunks to decrease file size
/// Gets or sets a the optimize method.
/// </summary>
public bool Optimized { get; set; }
public PngOptimizeMethod? OptimizeMethod { get; set; }
}
}

49
src/ImageSharp/Formats/Png/PngOptimizeMethod.cs

@ -0,0 +1,49 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
namespace SixLabors.ImageSharp.Formats.Png
{
/// <summary>
/// Provides enumeration of available PNG optimization methods.
/// </summary>
[Flags]
public enum PngOptimizeMethod
{
/// <summary>
/// With the None filter, the scanline is transmitted unmodified.
/// </summary>
None = 0,
/// <summary>
/// Suppress the physical dimension information chunk.
/// </summary>
SuppressPhysicalChunk = 1,
/// <summary>
/// Suppress the gamma information chunk.
/// </summary>
SuppressGammaChunk = 2,
/// <summary>
/// Suppress the eXIf chunk.
/// </summary>
SuppressExifChunk = 4,
/// <summary>
/// Suppress the tTXt, iTXt or zTXt chunk.
/// </summary>
SuppressTextChunks = 8,
/// <summary>
/// Make funlly transparent pixels black.
/// </summary>
MakeTransparentBlack = 16,
/// <summary>
/// All possible optimizations.
/// </summary>
All = 31,
}
}
Loading…
Cancel
Save