Labs · PNG card tool
JSON in, PNG out.
Or the other way around.
Pull the raw JSON out of a PNG character card, or embed a card into any image as proper chara / ccv3 chunks — byte-level PNG surgery, done locally in your browser.
Drop a PNG character card here, or click to choose
.png (card image with chara / ccv3 chunks)
All byte-level work happens in your browser — nothing uploads, nothing is stored. Works offline once loaded.
Extraction results appear here.
How the byte-level work is done
The reader walks every PNG chunk and accepts card data in tEXt, iTXt and zTXt forms, preferring ccv3 over chara — the same order the SillyTavern family uses, and the same reader behavior we verified against 34 real community card files while building the app's import pipeline. The writer assembles chunks by the book: length, type, data, then a CRC32 computed over type plus data, inserted after IHDR and before the image data.
Before writing, any card chunks the base image already carries get stripped — chara, ccv3, in all three text-chunk forms — so you never end up with one image carrying two different cards. Every embed is round-trip tested in development: embed, extract, compare byte-for-byte.
What it doesn't do
It never touches pixels — embedding adds metadata chunks, nothing more, and extraction reads them. The chunks are plain base64, not encryption: anyone with this page can read any card PNG, which is exactly how the format works everywhere. Site-specific private fields inside the JSON are carried through untouched and unexplained. And .charx zip containers aren't accepted on the embed side — convert those to JSON first with the format converter.
FAQ
Why does a screenshot of a card PNG lose the character data?
The persona lives in PNG text chunks (chara / ccv3), not in the pixels. A screenshot re-renders only the pixels; chat apps and social platforms re-compress images the same way. The image survives, the chunks don't. Always pass card PNGs around as files, and rebuild lost ones here from the JSON.
What are the chara and ccv3 chunks?
Two conventional PNG tEXt chunks that the SillyTavern family uses to carry card JSON as base64. chara is the classic V2-era keyword; ccv3 is the chara_card_v3 keyword, and readers prefer it when both exist. This tool writes chara always, plus ccv3 when the card declares spec chara_card_v3 — matching how mainstream exporters double-write.
Will SillyTavern and other frontends read the PNG this tool builds?
Yes. The output is a standard PNG with tEXt chunks placed between IHDR and the image data — readers in SillyTavern, RisuAI and Foreverse walk all chunks, so placement doesn't matter to them. We verified round-trips byte-for-byte: embed, re-extract, and the JSON comes back identical.
Is my card or image uploaded anywhere?
No. Chunk parsing, base64 coding, CRC32 checksums and JPG-to-PNG transcoding all run in your browser with standard web APIs. The page keeps working offline once loaded. If a card is private, it stays private.