Portable Network Graphics Encoder and Decoder written in Nim store lossless image with good compression.
Notable releases:
all PNG standard color mode are supported:
both interlaced and non-interlaced mode supported
recognize all PNG standard chunks: IHDR, IEND, PLTE, IDAT, tRNS, bKGD, pHYs, tIME, iTXt, zTXt tEXt, gAMA, cHRM, sRGB, iCCP, sBIT, sPLT, hIST
unknown chunks will be handled properly
the following chunks are supported (generated/interpreted) by both encoder and decoder:
the following chunks are parsed correctly, but not used by decoder: cHRM, gAMA, iCCP, sRGB, sBIT, hIST, sPLT
Supported color conversions:
import nimPNG
let png = loadPNG32("image.png")
# is equivalent to:
# let png = loadPNG("image.png", LCT_RGBA, 8)
# will produce rgba pixels:
# png.width -> width of the image
# png.height -> height of the image
# png.data -> pixels data in RGBA format
if you already have the whole file in memory:
let png = decodePNG32(raw_bytes)
# will do the same as above
other variants:
to create PNG:
special notes:
pixels are stored as raw bytes using Nim's string
/seq[T]
as container:
Byte Order | Format |
---|---|
r1,g1,b1,a1,...,rn,gn,bn,an | RGBA 8 bit |
r1,g1,b1,r2,g2,b2,...,rn,gn,bn | RGB 8 bit |
grey1,grey2,grey3, ..., greyn | GREY 8 bit |
grey1,a1,grey2,a2,...,greyn,an | GREY ALPHA 8 bit |
Since version 0.2.0, nimPNG provides support for Animated PNG.
Both decoder and encoder recognize/generate APNG chunks correctly: acTL, fcTL, fdAT.
Decoded frames is provided as is, the dimension and coordinate offset might be different with default frame. No alpha blending or other blending method performed. It is up to the application to do proper in-memory rendering before displaying the animation. Don't ask how to do it, any decent graphics rendering library have their own set of API to do alpha blending and offset rendering. In the future nimPNG might be shipped with simple frame rendering utility for common cases. Right now nimPNG is just a PNG encoder/decoder.
#let png = loadPNG32("image.png")
# or
#let png = loadPNG("image.png", LCT_RGBA, 8)
# or
#let png = decodePNG32(raw_bytes)
The usual loadPNG and decodePNG can decode both unanimated and animated PNG.
png.width
, png.height
, png.data
works as usual. If the decoded PNG is an APNG, png.data
will contains default frame.
Animation frames can be accessible via png.frames
. If it is not an APNG, png.frames
will be have zero length.
var png = prepareAPNG24(numPlays)
prepareAPNG
, prepareAPNG24
, or prepareAPNG32
. You also can specify how many times the animation
will be played png.addDefaultImage(framePixels, w, h, ctl)
addDefaultImage
. ctl
is optional, if you provide a ctl
(Frame Control),
the default image will be part of the animation. If ctl
is nil, default image will not be part of animation. png.addFrame(frames[i].data, ctl)
addFrame
one or more times. Here ctl
is mandatory. png.saveAPNG("rainbow.png")
# or
var str = png.encodeAPNG()
saveAPNG
if you want save it to a file or call encodeAPNG
if you want to get the result in memory.You can read the details of frame control from spec. You can also see an example in tester/test.nim -> generateAPNG
nimble install nimPNG