PngSharp 0.6.0
dotnet add package PngSharp --version 0.6.0
NuGet\Install-Package PngSharp -Version 0.6.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PngSharp" Version="0.6.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PngSharp" Version="0.6.0" />
<PackageReference Include="PngSharp" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PngSharp --version 0.6.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: PngSharp, 0.6.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package PngSharp@0.6.0
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=PngSharp&version=0.6.0
#tool nuget:?package=PngSharp&version=0.6.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
PngSharp
A fast, low-allocation, pure C# PNG encoder/decoder with zero native dependencies.
Features
- All color types and bit depths (1, 2, 4, 8, 16) per the PNG spec
- Adam7 interlacing (encode and decode)
- All 5 adaptive filter types with per-scanline selection
- Chunks: IHDR, PLTE, IDAT, IEND, tRNS, sRGB, gAMA, pHYs, cHRM, tIME, bKGD, sBIT, iCCP, eXIf, tEXt, zTXt, iTXt
- Chunk ordering validation per the PNG spec
- Multi-IDAT chunk encoding for large images
- CRC-32 validation on all chunks
- Stackalloc and span-based paths to minimize heap allocations
Decoding
// Decode from a file
var png = Png.DecodeFromFile("image.png");
// Decode from a byte array
var png = Png.DecodeFromByteArray(bytes);
// Decode from a stream
var png = Png.DecodeFromStream(stream);
// Access image data
var ihdr = png.Ihdr;
Console.WriteLine($"{ihdr.Width}x{ihdr.Height}, {ihdr.GetBytesPerPixel()} bytes per pixel");
byte[] pixels = png.PixelData;
// Helper extension methods
PngSize size = png.GetDimensions(); // (Width, Height) tuple
long bytes = png.GetMemorySize(); // total pixel data size in bytes
bool alpha = png.HasAlphaChannel(); // true for GrayscaleWithAlpha / TrueColorWithAlpha
bool palette = png.HasPalette(); // true for IndexedColor
bool gray = png.IsGrayscale(); // true for Grayscale / GrayscaleWithAlpha
Encoding
// Encode to a file
Png.EncodeToFile(png, "output.png");
// Encode to a byte array
byte[] bytes = Png.EncodeToByteArray(png);
// Encode to a stream
Png.EncodeToStream(png, stream);
Creating images from raw pixel data
// RGBA (4 bytes per pixel)
var rgba = Png.CreateRgba(width, height, pixelData);
// RGB (3 bytes per pixel)
var rgb = Png.CreateRgb(width, height, pixelData);
// Grayscale (1 byte per pixel)
var gray = Png.CreateGrayscale(width, height, pixelData);
// Grayscale with alpha (2 bytes per pixel)
var grayAlpha = Png.CreateGrayscaleWithAlpha(width, height, pixelData);
// Then encode
Png.EncodeToFile(rgba, "output.png");
Builder
For full control over the PNG structure, use the builder:
var png = Png.Builder()
.WithIhdr(new IhdrChunkData
{
Width = 256,
Height = 256,
BitDepth = 8,
ColorType = ColorType.TrueColorWithAlpha,
CompressionMethod = CompressionMethod.DeflateWithSlidingWindow,
FilterMethod = FilterMethod.AdaptiveFiltering,
InterlaceMethod = InterlaceMethod.None,
})
.WithPixelData(pixelData)
.WithSrgb(new SrgbChunkData { RenderingIntent = RenderingIntent.Perceptual })
.WithGama(GammaChunkData.FromDouble(0.45455)) // or set raw: new GammaChunkData { Value = 45455 }
.WithPhys(PhysChunkData.FromDpi(96, 96)) // or set raw PPU values
.Build();
Png.EncodeToFile(png, "output.png");
Adam7 interlaced encoding
var png = Png.Builder()
.WithIhdr(new IhdrChunkData
{
Width = 256,
Height = 256,
BitDepth = 8,
ColorType = ColorType.TrueColorWithAlpha,
CompressionMethod = CompressionMethod.DeflateWithSlidingWindow,
FilterMethod = FilterMethod.AdaptiveFiltering,
InterlaceMethod = InterlaceMethod.Adam7,
})
.WithPixelData(pixelData)
.Build();
Png.EncodeToFile(png, "interlaced.png");
Interlaced images are automatically deinterlaced when decoded — png.PixelData always contains the final, non-interlaced pixel data.
Indexed color with palette and transparency
var png = Png.Builder()
.WithIhdr(new IhdrChunkData
{
Width = 16,
Height = 16,
BitDepth = 8,
ColorType = ColorType.IndexedColor,
CompressionMethod = CompressionMethod.DeflateWithSlidingWindow,
FilterMethod = FilterMethod.AdaptiveFiltering,
InterlaceMethod = InterlaceMethod.None,
})
.WithPlte(new PlteChunkData { Entries = [255, 0, 0, 0, 255, 0, 0, 0, 255] }) // red, green, blue
.WithTrns(new TrnsChunkData { Data = [255, 128, 0] }) // fully opaque, semi-transparent, fully transparent
.WithPixelData(pixelIndices)
.Build();
Text metadata
var png = Png.Builder()
.WithIhdr(ihdr)
.WithPixelData(pixelData)
// Uncompressed Latin-1 text (tEXt)
.WithTxtChunk(new TextChunk { Keyword = "Author", Text = "Jane Doe" })
// Compressed Latin-1 text (zTXt)
.WithZTxtChunk(ZTextChunk.Create(new ZTextContent { Keyword = "Comment", Text = "A long description..." }))
// International UTF-8 text (iTXt)
.WithITxtChunk(ITextChunk.Create(new ITextContent
{
Keyword = "Title",
Text = "タイトル",
LanguageTag = "ja",
TranslatedKeyword = "タイトル",
}))
.Build();
Significant bits
var png = Png.Builder()
.WithIhdr(ihdr)
.WithPixelData(pixelData)
// sBIT: original significant bits per channel (e.g. 5-6-5 RGB source)
.WithSbit(new SbitChunkData { Data = [5, 6, 5] }) // length depends on color type
.Build();
ICC color profile
// Embed an ICC profile (mutually exclusive with sRGB)
var content = new IccpChunkContent { ProfileName = "sRGB IEC61966-2.1", RawProfile = iccBytes };
var png = Png.Builder()
.WithIhdr(ihdr)
.WithPixelData(pixelData)
.WithIccp(IccpChunkData.Encode(content))
.Build();
// Read it back
var profile = png.Iccp!.Value.Decode();
Console.WriteLine($"Profile: {profile.ProfileName}, {profile.RawProfile.Length} bytes");
EXIF metadata
// Embed raw EXIF data (must start with "MM" or "II" byte order mark)
var png = Png.Builder()
.WithIhdr(ihdr)
.WithPixelData(pixelData)
.WithExif(new ExifChunkData { Data = exifBytes })
.Build();
Chromaticities, background color, and modification time
var png = Png.Builder()
.WithIhdr(ihdr)
.WithPixelData(pixelData)
.WithChrm(new ChrmChunkData
{
WhitePointX = 31270, WhitePointY = 32900,
RedX = 64000, RedY = 33000,
GreenX = 30000, GreenY = 60000,
BlueX = 15000, BlueY = 6000,
})
.WithBkgd(new BkgdChunkData { Data = [0, 0, 0, 0, 0, 0] }) // black background (RGB, 2 bytes each)
.WithTime(TimeChunkData.FromDateTimeOffset(DateTimeOffset.UtcNow))
.Build();
Reading text chunks
var png = Png.DecodeFromFile("image.png");
foreach (var txt in png.TxtChunks)
Console.WriteLine($"{txt.Keyword}: {txt.Text}");
foreach (var ztxt in png.ZTxtChunks)
{
var content = ztxt.DecodeContent();
Console.WriteLine($"{content.Keyword}: {content.Text}");
}
foreach (var itxt in png.ITxtChunks)
{
var content = itxt.DecodeContent();
Console.WriteLine($"{content.Keyword} [{content.LanguageTag}]: {content.Text}");
}
Chunk Data Helpers
Several chunk data structs provide convenience methods for common conversions:
// Physical dimensions (pHYs) — DPI conversion
var phys = PhysChunkData.FromDpi(300, 300);
double dpiX = phys.GetDpiX(); // 300.0
double dpiY = phys.GetDpiY(); // 300.0
// Gamma (gAMA) — double conversion
var gama = GammaChunkData.FromDouble(0.45455);
double gamma = gama.ToDouble(); // 0.45455
// Modification time (tIME) — DateTimeOffset conversion
var time = TimeChunkData.FromDateTimeOffset(DateTimeOffset.UtcNow);
DateTimeOffset dt = time.ToDateTimeOffset();
// ICC profile (iCCP) — compress/decompress
var iccp = IccpChunkData.Encode(new IccpChunkContent { ProfileName = "sRGB", RawProfile = rawBytes });
IccpChunkContent content = iccp.Decode();
// Chromaticities (cHRM) — scaled double conversion
var chrm = ChrmChunkData.Create(new ChrmChunkContent { WhitePointX = 0.3127, WhitePointY = 0.3290, ... });
ChrmChunkContent values = chrm.DecodeContent();
// IHDR helpers
int bpp = ihdr.GetBytesPerPixel();
int bitsPerPixel = ihdr.GetBitsPerPixel();
int scanlineBytes = ihdr.GetScanlineByteWidth();
Configuration
// Optional: specify a logger to see debug information
Png.Logger = new ConsoleLogger();
// Optional: specify a custom file system
Png.FileSystem = new CustomFileSystem();
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net10.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.