{"id":13736583,"url":"https://github.com/jangko/nimPNG","last_synced_at":"2025-05-08T12:33:20.903Z","repository":{"id":43872000,"uuid":"41555352","full_name":"jangko/nimPNG","owner":"jangko","description":"PNG (Portable Network Graphics) decoder and encoder written in Nim","archived":false,"fork":false,"pushed_at":"2023-11-15T06:57:48.000Z","size":21021,"stargazers_count":90,"open_issues_count":7,"forks_count":12,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-11-09T20:49:58.577Z","etag":null,"topics":["apng-image","graphics","image","image-compression","png","png-decoder","png-encoder"],"latest_commit_sha":null,"homepage":"","language":"Nim","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jangko.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2015-08-28T15:40:13.000Z","updated_at":"2024-09-14T20:09:19.000Z","dependencies_parsed_at":"2023-01-29T17:15:41.413Z","dependency_job_id":"618675d0-d06a-464e-85f6-34398bdb5b9d","html_url":"https://github.com/jangko/nimPNG","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jangko%2FnimPNG","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jangko%2FnimPNG/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jangko%2FnimPNG/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jangko%2FnimPNG/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jangko","download_url":"https://codeload.github.com/jangko/nimPNG/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224732129,"owners_count":17360416,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apng-image","graphics","image","image-compression","png","png-decoder","png-encoder"],"created_at":"2024-08-03T03:01:24.475Z","updated_at":"2025-05-08T12:33:20.889Z","avatar_url":"https://github.com/jangko.png","language":"Nim","funding_links":[],"categories":["Multimedia"],"sub_categories":["Images"],"readme":"# nimPNG (PNG + APNG)\nPortable Network Graphics Encoder and Decoder written in Nim store lossless image with good compression.\n\nNotable releases:\n- 0.2.0 support Animated PNG!\n- 0.2.6 compile with --gc:arc.\n- 0.3.0 [new set of API](apidoc.md) using seq[uint8] and new method to handle error.\n- 0.3.1 fix new API bug and add openArray API\n\n![nimble](https://img.shields.io/badge/available%20on-nimble-yellow.svg?style=flat-square)\n![license](https://img.shields.io/github/license/citycide/cascade.svg?style=flat-square)\n![Github action](https://github.com/jangko/nimPNG/workflows/CI/badge.svg)\n\nall PNG standard color mode are supported:\n\n- LCT_GREY = 0,       # greyscale: 1,2,4,8,16 bit\n- LCT_RGB = 2,        # RGB: 8,16 bit\n- LCT_PALETTE = 3,    # palette: 1,2,4,8 bit\n- LCT_GREY_ALPHA = 4, # greyscale with alpha: 8,16 bit\n- LCT_RGBA = 6        # RGB with alpha: 8,16 bit\n\nboth interlaced and non-interlaced mode supported\n\nrecognize all PNG standard chunks:\nIHDR, IEND, PLTE, IDAT, tRNS, bKGD, pHYs, tIME, iTXt, zTXt\ntEXt, gAMA, cHRM, sRGB, iCCP, sBIT, sPLT, hIST\n\nunknown chunks will be handled properly\n\nthe following chunks are supported (generated/interpreted) by both encoder and decoder:\n\n- IHDR: header information\n- PLTE: color palette\n- IDAT: pixel data\n- IEND: the final chunk\n- tRNS: transparency for palettized images\n- tEXt: textual information\n- zTXt: compressed textual information\n- iTXt: international textual information\n- bKGD: suggested background color\n- pHYs: physical dimensions\n- tIME: modification time\n\nthe following chunks are parsed correctly, but not used by decoder:\ncHRM, gAMA, iCCP, sRGB, sBIT, hIST, sPLT\n\nSupported color conversions:\n\n- anything to 8-bit RGB, 8-bit RGBA, 16-bit RGB, 16-bit RGBA\n- any grey or grey+alpha, to grey or grey+alpha\n- anything to a palette, as long as the palette has the requested colors in it\n- removing alpha channel\n- higher to smaller bitdepth, and vice versa\n\n### Planned Feature(s):\n- streaming for progressive loading\n\n## Basic Usage\n```Nim\nimport nimPNG\n\nlet png = loadPNG32(\"image.png\")\n# is equivalent to:\n# let png = loadPNG(\"image.png\", LCT_RGBA, 8)\n# will produce rgba pixels:\n# png.width -\u003e width of the image\n# png.height -\u003e height of the image\n# png.data -\u003e pixels data in RGBA format\n```\n\nif you already have the whole file in memory:\n\n```Nim\nlet png = decodePNG32(raw_bytes)\n# will do the same as above\n```\n\nother variants:\n\n* loadPNG24 -\u003e will produce pixels in RGB format 8 bpp\n* decodePNG24 -\u003e load png from memory instead of file\n\nto create PNG:\n\n* savePNG32(\"output.png\", rgba_pixels, width, height) or savePNG24\n* encodePNG32(rgba_pixels, width, height) or encodePNG24\n\nspecial notes:\n\n* Use **loadPNG** or **savePNG** if you need specific input/output format by supplying supported **colorType** and **bitDepth** information.\n* Use **encodePNG** or **decodePNG** to do *in-memory* encoding/decoding by supplying desired **colorType** and **bitDepth** information.\n\npixels are stored as raw bytes using Nim's `string`/`seq[T]` as container:\n\n|           Byte Order           |      Format      |\n|:------------------------------:|:----------------:|\n| r1,g1,b1,a1,...,rn,gn,bn,an    | RGBA 8 bit       |\n| r1,g1,b1,r2,g2,b2,...,rn,gn,bn | RGB 8 bit        |\n| grey1,grey2,grey3, ..., greyn  | GREY 8 bit       |\n| grey1,a1,grey2,a2,...,greyn,an | GREY ALPHA 8 bit |\n\n## Animated PNG (APNG)\n\nSince version 0.2.0, nimPNG provides support for [Animated PNG](https://en.wikipedia.org/wiki/APNG).\n\nBoth decoder and encoder recognize/generate APNG chunks correctly: acTL, fcTL, fdAT.\n\nDecoded frames is provided as is, the dimension and coordinate offset might be different with default frame.\nNo alpha blending or other blending method performed.\nIt is up to the application to do proper in-memory rendering before displaying the animation.\nDon't ask how to do it, any decent graphics rendering library have their own set of API to do alpha blending and\noffset rendering. In the future nimPNG might be shipped with simple frame rendering utility for common cases.\nRight now nimPNG is just a PNG encoder/decoder.\n\n### Decoding\n\n```Nim\n#let png = loadPNG32(\"image.png\")\n# or\n#let png = loadPNG(\"image.png\", LCT_RGBA, 8)\n# or\n#let png = decodePNG32(raw_bytes)\n```\n\nThe usual loadPNG and decodePNG can decode both unanimated and animated PNG.\n`png.width`, `png.height`, `png.data` works as usual. If the decoded PNG is an APNG, `png.data` will contains default frame.\nAnimation frames can be accessible via `png.frames`. If it is not an APNG, `png.frames` will be have zero length.\n\n### Encoding\n\n```Nim\nvar png = prepareAPNG24(numPlays)\n```\n\n* First step is to call `prepareAPNG`, `prepareAPNG24`, or `prepareAPNG32`. You also can specify how many times the animation\nwill be played\n\n```Nim\n  png.addDefaultImage(framePixels, w, h, ctl)\n```\n\n* Second step is also mandatory, you should call `addDefaultImage`. `ctl` is optional, if you provide a `ctl`(Frame Control),\nthe default image will be part of the animation. If `ctl` is nil, default image will not be part of animation.\n\n```Nim\n  png.addFrame(frames[i].data, ctl)\n```\n\n* Third step is calling `addFrame` one or more times. Here `ctl` is mandatory.\n\n```Nim\n  png.saveAPNG(\"rainbow.png\")\n  # or\n  var str = png.encodeAPNG()\n```\n\n* Final step is to call `saveAPNG` if you want save it to a file or call `encodeAPNG` if you want to get the result in memory.\n\nYou can read the details of frame control from [spec](https://wiki.mozilla.org/APNG_Specification).\nYou can also see an example in tester/test.nim -\u003e generateAPNG\n\n## Installation via nimble\n\u003e nimble install nimPNG\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjangko%2FnimPNG","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjangko%2FnimPNG","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjangko%2FnimPNG/lists"}