Library and command-line tool to read NovelAI data encoded in PNG files
Project description
naipng ✒️🖼️
naipng is a Python library and command-line tool to read NovelAI
data encoded in PNG files (like in Lorebook cards and generated images), with no dependencies.
Also check out my website pngmeta for a browser-based tool for
viewing and copying PNG tEXt metadata.
Table of Contents
What Is This?
User-made content for the web service NovelAI is often shared off-platform in the form of files. These files take on multiple formats. Though most are simple JSON, some content can be shared embedded within PNGs, which is more complicated to extract.
Text Generation: NovelAI allows exporting certain settings and objects related to text generation AI as PNG images in place of regular JSON files, as a way of associating art with the descriptions of characters and places being shared. These are commonly known as Lorebook cards.
Image Generation: NovelAI encodes image generation settings within generated PNGs, including parameters
such as prompt, steps, and so on, to make it easier to replicate and modify generated images.
Both domains use PNG metadata to encode this information, thus this tool allows the extraction of that metadata.
See more technical details in the Technical Background section.
Installation
naipng is available on PyPI, so it can be installed through pip:
python -m pip install naipng
Since naipng has no dependencies, you can also import or run it by simply adding the naipng directory
to your source tree.
Usage
naipng may be used either as a library or a command-line tool.
Library
The primary function entrypoint provided by naipng is naipng.read(file: bytes | BinaryIO).
This can be used to parse a PNG image for NovelAI metadata from either an open file or a bytes object in memory.
Two more specific variations of naipng.read() also exist:
naipng.read_text_gen(file: bytes | BinaryIO)only returns text generation data- E.g. Lorebooks
naipng.read_image_gen(file: bytes | BinaryIO)only returns image generation data- E.g. image prompts
naipng.read() Example
import naipng
# Using a file-like object
with open("image.png", "rb") as file:
decoded = naipng.read(file)
if decoded is None:
# No NovelAI data found encoded in the image
print("N/A")
else:
# naipng.read() returns a dict object representing the first data found
for k, v in decoded.items():
print(k, "->", v)
Another example, using bytes as input to naipng.read:
import naipng
import pathlib
data: bytes = pathlib.Path("image.png").read_bytes()
decoded = naipng.read(data)
# ...
Error Handling
naipng defines two error types for naipng.read() and its variants:
naipng.InvalidPNGErroris raised when a PNG is invalid and cannot be parsed, such as when:- The PNG datastream ends prematurely (before
IEND) - A
tEXtchunk is corrupted (i.e. has an invalid CRC) - The PNG signature is missing
- The PNG
IHDRchunk is missing or misplaced
- The PNG datastream ends prematurely (before
naipng.NAIDataErroris raised when a PNG has atEXtchunk designated asnaidata, but it was unable to be decoded properly- This is never raised for
naipng.read_image_gen()
- This is never raised for
Both error classes derive from ValueError.
This example shows the behaviour of naipng.read with an invalid PNG datastream
(correct signature, but ends early).
import naipng
# Using a bytes object as input (a file-like object could be used too)
with open("image.png", "rb") as file:
# The datastream is truncated, rendering it invalid
data = file.read(10)
try:
naipng.read(data)
except naipng.InvalidPNGError as e:
raise SystemExit(f"Error: {e}") from e
This outputs:
Error: not a valid PNG file: ends prematurely
CLI
naipng may be invoked on the command line as either python -m naipng <file> or simply naipng <file>.
Help Text
usage: naipng [-h] [-q] [-c] [-t] [-i] file [outfile]
read NovelAI data encoded in a PNG file
positional arguments:
file PNG file to read, or - for stdin
outfile output file path, or - for stdout (default: -)
options:
-h, --help show this help message and exit
-q, --quiet don't print errors
-c, --compact don't pretty-print decoded JSON
-t, --text only check for text generation data
-i, --image only check for image generation data
Examples
- Printing to stdout:
naipng image.png
- Saving to a file:
naipng image.png naidata.json
- Saving to a file by redirecting
stdinandstdout:
naipng - < image.png > naidata.json
- Downloading via
curland piping PNG data throughstdin:
curl -fs https://files.catbox.moe/3b6dux.png | naipng -
naipng may be used in shell pipelines alongside JSON-parsing tools like jq
in order to construct more complex scripts.
$ curl -fs https://files.catbox.moe/3b6dux.png | naipng -c - | jq -r ".[\"entries\"][][\"text\"]"
Everyone said that no man now living or ever after would be born who would be equal to him in strength, courage, and in all sorts of courtesy, as well as in boldness and generosity that he had above all men, and that his name would never perish in the German tongue, and the same was true with the Norsemen
Trivia
The linked file is the first Lorebook card shared as an example when PNG embedding was announced. Its art is by Tarmillustrates. The quote in it is from Þiðreks saga.
Technical Background
PNGs are made up of a sequence of data chunks. Beyond those used to store visual information (e.g. pixels, palettes), there are also several varieties of metadata chunks. See the official PNG specification for full details.
NovelAI uses tEXt metadata chunks
to encode most metadata.
- For text generation settings, NovelAI uses a
tEXtchunk with anaidatakeyword.- The contents are base64-encoded JSON.
naidatais a nonstandardtEXtkeyword, so recognizing these chunks is unambiguous.
- For image generation settings, NovelAI uses multiple
tEXtchunks, each with different keywords.- Some of these include
Title,Description,Software,Source, andComment. naipngonly reads theCommentfield among these, which is JSON-encoded and contains the most information.Commentis a standardtEXtkeyword, so recognizing these chunks is slightly ambiguous.- Other software may use the
CommenttEXtchunk type for other purposes, and may or may not store JSON in it. naipngassumes that the first JSON-encodedCommenttEXtchunk found is valid image generation metadata.
- Other software may use the
- Some of these include
License
naipng is free and open-source software provided under the zlib license.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file naipng-1.0.0.post4.tar.gz.
File metadata
- Download URL: naipng-1.0.0.post4.tar.gz
- Upload date:
- Size: 12.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2968661b6e6a64126d73a3a46d409169f831e3270f5ed79c438f94ff888753d6
|
|
| MD5 |
dc4a93c091997094cec4fbf025a46374
|
|
| BLAKE2b-256 |
ca268ec23382a9aab698e4791c250a1d4554e40646be3aabf079669e31d5479b
|
File details
Details for the file naipng-1.0.0.post4-py3-none-any.whl.
File metadata
- Download URL: naipng-1.0.0.post4-py3-none-any.whl
- Upload date:
- Size: 11.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c246e8a2d07908d18757fa4587e55e69ad37db86c5bb9f0c57c836c59a8cf227
|
|
| MD5 |
d2fc318d0384b2ee39242db7c7439ef1
|
|
| BLAKE2b-256 |
66f4750bc7f1e87c60d8e51dcdf51f0610b355bbee83618a78e74deba8383b94
|