PNG/Png.cs

81 lines
2.7 KiB
C#
Raw Normal View History

2024-11-03 22:34:26 +01:00
namespace Uwaa.PNG;
/// <summary>
/// A PNG image. Call <see cref="Open(byte[])"/> to open from file or bytes.
/// </summary>
public class Png
{
readonly RawPngData data;
readonly bool hasTransparencyChunk;
/// <summary>
/// The header data from the PNG image.
/// </summary>
public ImageHeader Header { get; }
/// <summary>
/// The width of the image in pixels.
/// </summary>
public int Width => Header.Width;
/// <summary>
/// The height of the image in pixels.
/// </summary>
public int Height => Header.Height;
/// <summary>
/// Whether the image has an alpha (transparency) layer.
/// </summary>
public bool HasAlphaChannel => (Header.ColorType & ColorType.AlphaChannelUsed) != 0 || hasTransparencyChunk;
internal Png(ImageHeader header, RawPngData data, bool hasTransparencyChunk)
{
Header = header;
this.data = data ?? throw new ArgumentNullException(nameof(data));
this.hasTransparencyChunk = hasTransparencyChunk;
}
/// <summary>
/// Get the pixel at the given column and row (x, y).
/// </summary>
/// <remarks>
/// Pixel values are generated on demand from the underlying data to prevent holding many items in memory at once, so consumers
/// should cache values if they're going to be looped over many time.
/// </remarks>
/// <param name="x">The x coordinate (column).</param>
/// <param name="y">The y coordinate (row).</param>
/// <returns>The pixel at the coordinate.</returns>
public Pixel GetPixel(int x, int y) => data.GetPixel(x, y);
/// <summary>
/// Read the PNG image from the stream.
/// </summary>
/// <param name="stream">The stream containing PNG data to be read.</param>
/// <returns>The <see cref="Png"/> data from the stream.</returns>
public static Png Open(Stream stream)
=> PngOpener.Open(stream);
/// <summary>
/// Read the PNG image from the bytes.
/// </summary>
/// <param name="bytes">The bytes of the PNG data to be read.</param>
/// <returns>The <see cref="Png"/> data from the bytes.</returns>
public static Png Open(byte[] bytes)
{
using var memoryStream = new MemoryStream(bytes);
return PngOpener.Open(memoryStream);
}
/// <summary>
/// Read the PNG from the file path.
/// </summary>
/// <param name="path">The path to the PNG file to open.</param>
/// <remarks>This will open the file to obtain a <see cref="FileStream"/> so will lock the file during reading.</remarks>
/// <returns>The <see cref="Png"/> data from the file.</returns>
public static Png Open(string path)
{
using var fileStream = File.OpenRead(path);
return Open(fileStream);
}
}