-
-
Notifications
You must be signed in to change notification settings - Fork 419
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add PngWriteDefines to Magick.NET (#1661)
- Loading branch information
1 parent
b6210a6
commit 31acab3
Showing
13 changed files
with
680 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// Copyright Dirk Lemstra https://github.com/dlemstra/Magick.NET. | ||
// Licensed under the Apache License, Version 2.0. | ||
|
||
using System; | ||
|
||
namespace ImageMagick.Formats; | ||
|
||
/// <summary> | ||
/// Specifies the chunks to be included or excluded in the PNG image. | ||
/// This is a flags enumeration, allowing a bitwise combination of its member values. | ||
/// </summary> | ||
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1300:Element should begin with upper-case letter", Justification = "The lowercase names are consistent with the naming conventions of PNG chunk types as defined in the PNG specification.")] | ||
[Flags] | ||
public enum PngChunkFlags | ||
{ | ||
/// <summary> | ||
/// No chunks specified. | ||
/// </summary> | ||
None = 0, | ||
|
||
/// <summary> | ||
/// Include or exclude all chunks. | ||
/// </summary> | ||
All = bKGD | cHRM | EXIF | gAMA | iCCP | iTXt | sRGB | tEXt | zCCP | zTXt | date, | ||
|
||
/// <summary> | ||
/// Include or exclude bKGD chunk. | ||
/// </summary> | ||
bKGD = 1, | ||
|
||
/// <summary> | ||
/// Include or exclude cHRM chunk. | ||
/// </summary> | ||
cHRM = 2, | ||
|
||
/// <summary> | ||
/// Include or exclude EXIF chunk. | ||
/// </summary> | ||
EXIF = 4, | ||
|
||
/// <summary> | ||
/// Include or exclude gAMA chunk. | ||
/// </summary> | ||
gAMA = 8, | ||
|
||
/// <summary> | ||
/// Include or exclude iCCP chunk. | ||
/// </summary> | ||
iCCP = 16, | ||
|
||
/// <summary> | ||
/// Include or exclude iTXt chunk. | ||
/// </summary> | ||
iTXt = 32, | ||
|
||
/// <summary> | ||
/// Include or exclude sRGB chunk. | ||
/// </summary> | ||
sRGB = 64, | ||
|
||
/// <summary> | ||
/// Include or exclude tEXt chunk. | ||
/// </summary> | ||
tEXt = 128, | ||
|
||
/// <summary> | ||
/// Include or exclude zCCP chunk. | ||
/// </summary> | ||
zCCP = 256, | ||
|
||
/// <summary> | ||
/// Include or exclude zTXt chunk. | ||
/// </summary> | ||
zTXt = 512, | ||
|
||
/// <summary> | ||
/// Include or exclude date chunk. | ||
/// </summary> | ||
date = 1024, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright Dirk Lemstra https://github.com/dlemstra/Magick.NET. | ||
// Licensed under the Apache License, Version 2.0. | ||
|
||
namespace ImageMagick.Formats; | ||
|
||
/// <summary> | ||
/// Specifies the PNG compression filter. | ||
/// </summary> | ||
public enum PngCompressionFilter | ||
{ | ||
/// <summary> | ||
/// 0 - None: No filter. | ||
/// </summary> | ||
None, | ||
|
||
/// <summary> | ||
/// Sub: Subtracts the value of the pixel to the left. | ||
/// </summary> | ||
Sub, | ||
|
||
/// <summary> | ||
/// Up: Subtracts the value of the pixel above. | ||
/// </summary> | ||
Up, | ||
|
||
/// <summary> | ||
/// Average: Uses the average of the left and above pixels. | ||
/// </summary> | ||
Average, | ||
|
||
/// <summary> | ||
/// Paeth: A predictive filter using the Paeth algorithm. | ||
/// </summary> | ||
Paeth, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// Copyright Dirk Lemstra https://github.com/dlemstra/Magick.NET. | ||
// Licensed under the Apache License, Version 2.0. | ||
|
||
namespace ImageMagick.Formats; | ||
|
||
/// <summary> | ||
/// Specifies the PNG compression strategy. | ||
/// </summary> | ||
public enum PngCompressionStrategy | ||
{ | ||
/// <summary> | ||
/// Use the Huffman compression. | ||
/// </summary> | ||
HuffmanOnly, | ||
|
||
/// <summary> | ||
/// Compression algorithm with filtering. | ||
/// </summary> | ||
Filtered, | ||
|
||
/// <summary> | ||
/// Use the Run-Length Encoding compression. | ||
/// </summary> | ||
RLE, | ||
|
||
/// <summary> | ||
/// Use a fixed strategy for compression. | ||
/// </summary> | ||
Fixed, | ||
|
||
/// <summary> | ||
/// Use the default compression strategy. | ||
/// </summary> | ||
Default, | ||
|
||
/// <summary> | ||
/// Adaptive filtering is used when quality is greater than 50 and the image does not have a color map; otherwise, no filtering is used. | ||
/// </summary> | ||
Adaptive, | ||
|
||
/// <summary> | ||
/// Adaptive filtering with minimum-sum-of-absolute-values is used. | ||
/// </summary> | ||
AdaptiveMinimumSum, | ||
|
||
/// <summary> | ||
/// LOCO color transformation (intrapixel differencing) and adaptive filtering with minimum-sum-of-absolute-values are used. Only applicable if the output is MNG. | ||
/// </summary> | ||
LOCO, | ||
|
||
/// <summary> | ||
/// The zlib Z_RLE compression strategy (or the Z_HUFFMAN_ONLY strategy when compression level is 0) is used with adaptive PNG filtering. | ||
/// </summary> | ||
ZRLEAdaptive, | ||
|
||
/// <summary> | ||
/// The zlib Z_RLE compression strategy (or the Z_HUFFMAN_ONLY strategy when compression level is 0) is used with no PNG filtering. | ||
/// </summary> | ||
ZRLENoFilter, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
// Copyright Dirk Lemstra https://github.com/dlemstra/Magick.NET. | ||
// Licensed under the Apache License, Version 2.0. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace ImageMagick.Formats; | ||
|
||
/// <summary> | ||
/// Class for defines that are used when a <see cref="MagickFormat.Png"/> image is written. | ||
/// </summary> | ||
public sealed class PngWriteDefines : IWriteDefines | ||
{ | ||
/// <summary> | ||
/// Gets or sets the bit depth for the PNG image. | ||
/// Valid values: 1, 2, 4, 8, 16. | ||
/// </summary> | ||
/// <exception cref="ArgumentException"> Thrown when the bit depth is invalid for the given color type.</exception> | ||
public uint? BitDepth { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the color type of the image. | ||
/// </summary> | ||
/// <exception cref="ArgumentException">Thrown when the color type is invalid or unsupported.</exception> | ||
public ColorType? ColorType { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the compression filter for the PNG image. | ||
/// For compression level 0 (quality value less than 10), the Huffman-only strategy is used, which is fastest but not necessarily the worst compression. | ||
/// </summary> | ||
public PngCompressionFilter? CompressionFilter { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the compression level for the PNG image. | ||
/// The compression level ranges from 0 to 9, where 0 indicates no compression and 9 indicates maximum compression. | ||
/// For compression level 0 (quality value less than 10), the Huffman-only strategy is used, which is the fastest but not necessarily the worst compression. | ||
/// </summary> | ||
public uint? CompressionLevel { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the compression strategy for the PNG image. | ||
/// </summary> | ||
public PngCompressionStrategy? CompressionStrategy { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the chunks to be excluded. | ||
/// </summary> | ||
public PngChunkFlags? ExcludeChunks { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the chunks to be included. | ||
/// </summary> | ||
public PngChunkFlags? IncludeChunks { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets a value indicating whether the iCCP chunk should be preserved when writing the image. | ||
/// </summary> | ||
public bool PreserveiCCP { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets a value indicating whether ColorMap should be preserve when writing the image. | ||
/// </summary> | ||
public bool PreserveColorMap { get; set; } | ||
|
||
/// <summary> | ||
/// Gets the format where the defines are for. | ||
/// </summary> | ||
public MagickFormat Format | ||
=> MagickFormat.Png; | ||
|
||
/// <summary> | ||
/// Gets the defines that should be set as a define on an image. | ||
/// </summary> | ||
public IEnumerable<IDefine> Defines | ||
{ | ||
get | ||
{ | ||
if (BitDepth.HasValue) | ||
yield return new MagickDefine(Format, "bit-depth", BitDepth.Value); | ||
|
||
if (ColorType.HasValue) | ||
{ | ||
var colorTypeValue = GetPngColorTypeValue(ColorType.Value); | ||
yield return new MagickDefine(Format, "color-type", (int)colorTypeValue); | ||
} | ||
|
||
if (CompressionFilter.HasValue) | ||
yield return new MagickDefine(Format, "compression-filter", (int)CompressionFilter.Value); | ||
|
||
if (CompressionLevel.HasValue) | ||
yield return new MagickDefine(Format, "compression-level", CompressionLevel.Value); | ||
|
||
if (CompressionStrategy.HasValue) | ||
yield return new MagickDefine(Format, "compression-strategy", (int)CompressionStrategy.Value); | ||
|
||
if (ExcludeChunks.HasValue) | ||
yield return new MagickDefine(Format, "exclude-chunks", EnumHelper.ConvertFlags(ExcludeChunks.Value)); | ||
|
||
if (IncludeChunks.HasValue) | ||
yield return new MagickDefine(Format, "include-chunks", EnumHelper.ConvertFlags(IncludeChunks.Value)); | ||
|
||
if (PreserveiCCP) | ||
yield return new MagickDefine(Format, "preserve-iCCP", PreserveiCCP); | ||
|
||
if (PreserveColorMap) | ||
yield return new MagickDefine(Format, "preserve-colormap", PreserveColorMap); | ||
} | ||
} | ||
|
||
private int GetPngColorTypeValue(ColorType colorType) | ||
{ | ||
// 0 - Grayscale | ||
// 2 - RGB (TrueColor) | ||
// 3 - Indexed color type (Palette or PaletteAlpha) | ||
// 4 - Grayscale with alpha (GrayscaleAlpha) | ||
// 6 - RGB with alpha (TrueColorAlpha) | ||
return colorType switch | ||
{ | ||
ImageMagick.ColorType.Grayscale => 0, | ||
ImageMagick.ColorType.TrueColor => 2, | ||
ImageMagick.ColorType.Palette or ImageMagick.ColorType.PaletteAlpha => 3, | ||
ImageMagick.ColorType.GrayscaleAlpha => 4, | ||
ImageMagick.ColorType.TrueColorAlpha => 6, | ||
_ => throw new ArgumentException($"Unsupported color type: {colorType}"), | ||
}; | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
tests/Magick.NET.Tests/Formats/Png/PngWriteDefinesTests/TheBitDepthProperty.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Copyright Dirk Lemstra https://github.com/dlemstra/Magick.NET. | ||
// Licensed under the Apache License, Version 2.0. | ||
|
||
using ImageMagick; | ||
using ImageMagick.Formats; | ||
using Xunit; | ||
|
||
namespace Magick.NET.Tests; | ||
|
||
public partial class PngWriteDefinesTests | ||
{ | ||
public class TheBitDepthProperty | ||
{ | ||
[Fact] | ||
public void ShouldSetTheDefine() | ||
{ | ||
using var image = new MagickImage(); | ||
image.Settings.SetDefines(new PngWriteDefines | ||
{ | ||
BitDepth = 8U, | ||
}); | ||
|
||
Assert.Equal("8", image.Settings.GetDefine(MagickFormat.Png, "bit-depth")); | ||
} | ||
|
||
[Fact] | ||
public void ShouldNotSetTheDefineWhenNull() | ||
{ | ||
using var image = new MagickImage(); | ||
image.Settings.SetDefines(new PngWriteDefines | ||
{ | ||
BitDepth = null, | ||
}); | ||
|
||
Assert.Null(image.Settings.GetDefine(MagickFormat.Png, "bit-depth")); | ||
} | ||
} | ||
} |
Oops, something went wrong.