# How to strip text chunks from a PNG

Source: https://passreal.com/how-to/strip-png-text-chunks

PNG stores arbitrary text in three chunk types: tEXt for plain Latin-1, zTXt for compressed text, and iTXt for UTF-8. Generation tools write prompts, model names and entire workflow graphs into them. `exiftool -all= file.png` removes them, and re-reading the file afterwards is the only way to confirm the removal rather than assume it.

## The three chunk types

A PNG is a sequence of chunks, each with a four-byte type, a length, a payload
and a checksum. Decoders ignore types they do not recognise, which is what makes
the format convenient for carrying arbitrary text.

`tEXt` holds an uncompressed keyword and value in Latin-1. This is where
Automatic1111 writes its `parameters` string: prompt, negative prompt, sampler,
step count, guidance scale, seed, model hash.

`zTXt` holds the same thing compressed with zlib. Longer payloads land here,
which is where an entire ComfyUI node graph tends to end up.

`iTXt` holds UTF-8 with an optional language tag, and is where XMP packets are
usually written, including provenance data.

A file can carry all three. Removing one and declaring the job done is a common
way to leave a prompt sitting in the file.

## Looking before removing

Read the file before changing it, because knowing what was there tells you what
to check for afterwards.

- `exiftool -a -G1 file.png` lists every tag with its group, including
  duplicates that a plain listing collapses.
- `pngcheck -v file.png` walks the chunk structure directly and names each
  chunk type in order, which catches private chunks that metadata tools skip.
- `strings file.png | head -50` is crude and effective: an uncompressed prompt
  is usually visible in the first few hundred bytes.

The last one is worth running after removal too. It costs nothing and it
occasionally finds something a structured tool reported as absent.

## Removing, and confirming

`exiftool -all= file.png` clears the metadata and leaves a `_original` backup
alongside. Confirm with a second read rather than trusting the exit status:

- `exiftool file.png` should report only physical properties.
- `pngcheck -v file.png` should list `IHDR`, `IDAT` and `IEND` with nothing
  textual in between.

For a directory, `exiftool -all= -overwrite_original -ext png .` processes
everything in place. On a batch that matters, run the verification across the
whole directory as well, because a single file that failed to write is silent
otherwise.

## What each tool writes, and where

Knowing which tool produced a file tells you where to look first, because the
conventions differ.

- Automatic1111 writes a single `tEXt` chunk keyed `parameters`, holding one
  long string with the prompt first and the settings after it.
- ComfyUI writes two: `prompt` with the API-format graph, and `workflow` with
  the full editor state including node positions. Both are JSON, both are large,
  and both name every model in the chain.
- InvokeAI writes its own `invokeai_metadata` key with a structured payload.
- Tools that export through Adobe libraries add an XMP packet in an `iTXt`
  chunk, which may carry a document identifier linking the file to others
  exported in the same session.
- Anything that signed on to content provenance adds a C2PA manifest, which is
  a signed claim rather than a plain field.

The document identifier is the one people miss. It does not name a generator,
so a quick look reads it as harmless, and it quietly links a set of files to a
common origin.

## What this does not fix

Metadata removal is complete and it is narrow. The pixels are untouched, so a
classifier reading noise statistics, corner sharpness or frequency residue sees
exactly what it saw before.

It also produces a file with no metadata at all, which is not what a camera
produces. The pipeline that this site runs handles both halves: chunks are
removed, then the sensor stage applies grain at intensity 0.018 and lateral
chromatic aberration reaching 1.25 px at the corners, the frequency stage
attenuates upsampling residue at 0.88 of Nyquist, and the encode writes
coherent camera EXIF with the matching quantization table.

## Questions

### What is the command?

`exiftool -all= image.png` strips metadata and writes `image.png_original` as a backup. Add `-overwrite_original` to skip the backup. Verify with `exiftool image.png`, which should then list only the physical properties: dimensions, bit depth, colour type.

### Does ImageMagick do the same thing?

`convert in.png -strip out.png` removes most chunks and is convenient inside an existing pipeline. It re-encodes the image, which exiftool does not, so the pixel data changes slightly. For metadata removal alone, exiftool is the more precise instrument.

### Are there chunks exiftool leaves behind?

It leaves the chunks a PNG needs to decode, which is correct. Some tools also write private chunks that are not text at all, and a raw hexdump for the chunk-type bytes is the way to see everything the file contains rather than everything one tool reports.

### Why does the file still get flagged after stripping?

Because the pixels were never touched. Stripping addresses metadata inspection only. A statistical classifier reads the image itself, and an image with no noise floor and uniformly sharp corners looks the same before and after a metadata pass.

### Is an empty metadata block suspicious in itself?

Somewhat. Cameras and phones always write EXIF, so a file with none is unusual among photographs. Stripping and then writing coherent camera metadata is a more complete answer than stripping alone.

Try it: https://passreal.com/app (three images free)
