Swiftpack.co - Package - kelvin13/png


Platforms Release tag Build Issues Language License KK26

The master branch contains the 3.0.0 version of this library. For 2.0.1, use the tagged release version.

A pure Swift PNG library. Enjoy fast PNG encoding and decoding with strong data types, strict validation, and a safe, expressive, and Swifty API.

getting started

Decode a PNG file to a type of your choice in just one function call.

import PNG

let (pixels, (x: width, y: height)) = try PNG.rgba(path: "example.png", of: UInt8.self)
// pixels: [PNG.RGBA<UInt8>]
// width:  Int
// height: Int

Use a component type of UInt16 to capture the full color depth of a 16-bit PNG.

let (pixels, (x: width, y: height)) = try PNG.rgba(path: "example.png", of: UInt16.self)
// pixels: [PNG.RGBA<UInt16>]
// width:  Int
// height: Int

Return only the components you need with the grayscale and grayscale-alpha APIs.

let (pixels, (x: width, y: height)) = try PNG.va(path: "example.png", of: UInt8.self)
// pixels: [PNG.VA<UInt8>]
// width:  Int
// height: Int
let (pixels, (x: width, y: height)) = try PNG.v(path: "example.png", of: UInt8.self)
// pixels: [UInt8]
// width:  Int
// height: Int



  • Supports all standard PNG formats, including indexed and interlaced formats
  • Supports common graphics API interchange formats such as ARGB32
  • Supports ancillary chunks, including private ancillary chunks
  • Supports chroma key transparency
  • Multi-level APIs, including raw chunk-level APIs
  • Strong typing and expressive enumerations to catch invalid states at compile time
  • Fixed-layout currency types for efficient C interop
  • No Foundation imports and one system dependency, zlib
  • Tested on MacOS and Linux
  • Thorough API documentation


What’s the difference between bit depth and color type?

Color type refers to the channels present in a PNG. A grayscale PNG has only one color channel, while an RGB PNG has three (red, green, and blue). An RGBA PNG has four — three color channels, plus one alpha channel. Similarly, a grayscale–alpha PNG has two — one grayscale “color” channel and one alpha channel. An indexed-color PNG has one encoded channel in the image data, but the colors the indices represent are always RGBA quadruples. The vast majority of PNGs in the world are either of color type RGB or RGBA.

Bit depth goes one level lower; it represents the size of each channel. A PNG with a bit depth of 8 has 8 bits per channel. Hence, one pixel of an RGBA PNG is 4 * 8 = 32 bits long, or 4 bytes.

What is interlacing?

Interlacing is a way of progressively ordering the image data in a PNG so it can be displayed at lower resolution even when partially downloaded. Interlacing is sometimes used in images on social media such as Instagram or Twitter, but rare elsewhere. Interlacing hurts compression, and so it usually significantly increases the size of a PNG file, sometimes as much as thirty percent.

Why does this package depend on zlib?

ZLib is a standard compression/decompression library that is installed by default on MacOS and most Linux systems. Although it is written in C, it is wrapped by almost every major programming language including Java and Python. The only other Swift PNG decoder library in existence at the time of writing, SwiftGL Image, actually implements its own, pure Swift, INFLATE algorithm. (Note that it doesn’t compile on Swift ≥3.1.)

Does this package work on MacOS?


How do I access/encode custom PNG metadata chunks?

Use the ancillary chunk API on the Data.Uncompressed or Data.Rectangular types, which expose ancillary chunk types and data through the ancillaries instance property. See this tutorial for more details. Note that, except for tRNS, PNG does not parse ancillary chunks, it only provides their data as a [UInt8] buffer. Consult the PNG specification to interpret the ancillary chunks.

Does this package do gamma correction?

No. Gamma is meant to be applied at the image display stage. PNG only gives you the base pixel values in the image (with indexed pixel dereferencing and chroma key substitution). Gamma is also easy to apply to raw color data but computationally expensive to remove. Some PNGs include gamma data in a chunk called gAMA, but most don’t, and viewers will just apply a γ = 2.2 regardless.


Build PNG with the swift package manager, swift build (-c release). Make sure you have the zlib headers on your computer (sudo apt-get install libz-dev).


Stars: 145
Help us keep the lights on


Used By

Total: 1


v3.0.0 - Jan 7, 2019

The library has been completely rewritten since version 2.0.1 and now features a much streamlined and improved API, as well as ancillary PNG chunk support, and a wider variety of color format inputs and outputs. Grayscale–alpha and indexed color now have first-class status in the 3.0 API, and are fully integrated with all PNG color backends in the file format’s specification. The typing system has also been greatly strengthened, resulting in an API which returns far fewer optionals, provides more expressive enumerations, and has a much greater chance of catching errors at compile time.

2.0.1 - May 21, 2017

This release adds a new overload to png_encode(path:raw_data:properties:chunk_size:) that takes a Swift UnsafeBufferPointer<UInt8> instead of an Array, to avoid having to recopy a foreign array into Swift managed memory.

2.0.0 - May 19, 2017

In addition to being faster and more memory-efficient, MaxPNG 2 brings new features:

  • Support for indexed-color and interlaced PNG files
  • Passes all PNG test suite test cases
  • Contiguous encoding and decoding functions, which are more efficient than the progressive variety
  • Support for chroma keys, which are split between the PLTE and tRNS chunks
  • RGBA normalization
  • Ability to generate premultiplied alpha
  • Ability to generate Cairo buffers from PNG files
  • Ability to decompose interlaced PNGs into their constituent subimages
  • Ability to encode indexed and interlaced PNG files
  • Increased safety and validation
  • Better-designed API and API naming
  • Full API documentation

1.0.0 - Feb 10, 2017