---
title: "Text protection"
url: https://phatdev.net/en/docs/pixgamma/giu-chu
lang: en
updated: 2026-10-22
alternate:
  vi: https://phatdev.net/docs/pixgamma/giu-chu
markdown: https://phatdev.net/en/docs/pixgamma/giu-chu.md
---

# Text protection

Part of the doc set: [PixGamma](https://phatdev.net/en/docs/pixgamma.md)

> How PixGamma finds, measures and rebuilds keycap, label and banner text, Vietnamese included; results and limits.

Text is where AI upscalers fail most: strokes bend, small letters become other letters, Vietnamese diacritics disappear. PixGamma handles text in a step of its own.

<div style="margin:1.6em 0"><figure style="margin:0"><a href="https://phatdev.net/uploads/p/pixgamma/compare-thinkpad-vi-light-3840.webp" target="_blank" rel="noopener" class="pd-th-light" style="display:block;border:0" aria-label="Product photos: a backlit ThinkPad keyboard from 480 px to 4x, every keycap letter correct (4K)"><img src="https://phatdev.net/uploads/p/pixgamma/compare-thinkpad-vi-light-1920.webp" srcset="/uploads/p/pixgamma/compare-thinkpad-vi-light-960.webp 960w, /uploads/p/pixgamma/compare-thinkpad-vi-light-1920.webp 1920w, /uploads/p/pixgamma/compare-thinkpad-vi-light-3840.webp 3840w" sizes="(max-width: 900px) 100vw, 760px" width="3840" height="2160" alt="Product photos: a backlit ThinkPad keyboard from 480 px to 4x, every keycap letter correct" loading="lazy" decoding="async" style="width:100%;height:auto;display:block;border:1px solid var(--line);border-radius:12px"></a><a href="https://phatdev.net/uploads/p/pixgamma/compare-thinkpad-vi-dark-3840.webp" target="_blank" rel="noopener" class="pd-th-dark" style="display:block;border:0" aria-label="Product photos: a backlit ThinkPad keyboard from 480 px to 4x, every keycap letter correct (4K)"><img src="https://phatdev.net/uploads/p/pixgamma/compare-thinkpad-vi-dark-1920.webp" srcset="/uploads/p/pixgamma/compare-thinkpad-vi-dark-960.webp 960w, /uploads/p/pixgamma/compare-thinkpad-vi-dark-1920.webp 1920w, /uploads/p/pixgamma/compare-thinkpad-vi-dark-3840.webp 3840w" sizes="(max-width: 900px) 100vw, 760px" width="3840" height="2160" alt="Product photos: a backlit ThinkPad keyboard from 480 px to 4x, every keycap letter correct" loading="lazy" decoding="async" style="width:100%;height:auto;display:block;border:1px solid var(--line);border-radius:12px"></a><figcaption style="margin-top:8px;font-size:13px;line-height:1.5;color:var(--muted);text-align:center">Product photos: a backlit ThinkPad keyboard from 480 px to 4x, every keycap letter correct</figcaption></figure></div>

<div style="margin:1.6em 0"><figure style="margin:0"><a href="https://phatdev.net/uploads/p/pixgamma/compare-ui-vi-light-3840.webp" target="_blank" rel="noopener" class="pd-th-light" style="display:block;border:0" aria-label="Screenshots: a 720 px UI at 2x, clearer text with Vietnamese diacritics (4K)"><img src="https://phatdev.net/uploads/p/pixgamma/compare-ui-vi-light-1920.webp" srcset="/uploads/p/pixgamma/compare-ui-vi-light-960.webp 960w, /uploads/p/pixgamma/compare-ui-vi-light-1920.webp 1920w, /uploads/p/pixgamma/compare-ui-vi-light-3840.webp 3840w" sizes="(max-width: 900px) 100vw, 760px" width="3840" height="2160" alt="Screenshots: a 720 px UI at 2x, clearer text with Vietnamese diacritics" loading="lazy" decoding="async" style="width:100%;height:auto;display:block;border:1px solid var(--line);border-radius:12px"></a><a href="https://phatdev.net/uploads/p/pixgamma/compare-ui-vi-dark-3840.webp" target="_blank" rel="noopener" class="pd-th-dark" style="display:block;border:0" aria-label="Screenshots: a 720 px UI at 2x, clearer text with Vietnamese diacritics (4K)"><img src="https://phatdev.net/uploads/p/pixgamma/compare-ui-vi-dark-1920.webp" srcset="/uploads/p/pixgamma/compare-ui-vi-dark-960.webp 960w, /uploads/p/pixgamma/compare-ui-vi-dark-1920.webp 1920w, /uploads/p/pixgamma/compare-ui-vi-dark-3840.webp 3840w" sizes="(max-width: 900px) 100vw, 760px" width="3840" height="2160" alt="Screenshots: a 720 px UI at 2x, clearer text with Vietnamese diacritics" loading="lazy" decoding="async" style="width:100%;height:auto;display:block;border:1px solid var(--line);border-radius:12px"></a><figcaption style="margin-top:8px;font-size:13px;line-height:1.5;color:var(--muted);text-align:center">Screenshots: a 720 px UI at 2x, clearer text with Vietnamese diacritics</figcaption></figure></div>

## How it works

1. **Find text.** Apple Vision runs in accurate mode with `vi-VT` and `en-US` on the source, on a 2x enlargement and on the upscaled result, so small keycap letters are caught too. The text read is included in the report (`text` in JSON).
2. **Complete lines.** Vision often stops a few letters early on small lines; regions are extended along the ink to the end of the line.
3. **Measure size from pixels.** Vision's boxes are off by 1–2 px on small text, so PixGamma measures each line's **vertical ink spread** directly on the pixels.
4. **Rebuild.** Text regions are run again through **PixGamma Photo v1** (trained with text tiles), averaged over 2 passes (as is and turned 180°) for straight strokes, and feathered in.
5. **Keep text color clean.** The color-preservation step skips text regions, so letters are not covered again by the source's blur.

## Measured results

The `eval_text_pipeline.py` benchmark renders Vietnamese and English banners in several fonts, shrinks them 4x and runs the full pipeline; each line is cropped and read by OCR on its own (Vision reads a line differently depending on its neighbours, so whole-banner scoring is noisy).

| Text region method | OCR correct | PSNR | Sharpness |
|---|---|---|---|
| No text protection | 90.3% | 29.1 dB | 0.47 |
| Dedicated Text v3 model (0.2.0) | 89.2% | 29.2 dB | 0.58 |
| **PixGamma Photo v1, 2 passes (0.2.1)** | **91.1%** | **30.5 dB** | **0.69** |

On a real MacBook keyboard photo shrunk 4x: whole-image PSNR rises from 23.8 to 25.1 dB, and around the Y key from 19.5 to 21.9 dB.

## Very small text

At capitals of about 3.6 px in the source, a Vietnamese tone mark is under a pixel. The old model drew crisp but wrong letters, so 0.2.0 faded such lines to a soft resample. PixGamma Photo v1 reads better than the soft resample at that size (76.1% vs 72.3%), so since 0.2.1 the fade only applies with the old text model.

PixGamma also tried **re-typesetting tiny text with fonts** from Vision's reading, accepted only when it matched the pixels, and dropped it: wrong readings matched the pixels almost as well as right ones.

> **Known limit:** text that Vision cannot find at all (for example body text under about 4 px on a sign in a heavily shrunk photo) is not protected, and every upscaling model can turn it into letter-like shapes. Use 2x instead of 4x, or High Fidelity, for such photos.

## Turning it off

In the app, in the adjustments panel; CLI `--no-text-protect`; API `text=0`. `PIXGAMMA_TEXT_TTA=1|2|4|8` sets the number of flip/rotation passes and `PIXGAMMA_TEXT_MODEL` forces another model for text regions (benchmarks).
