A free online generator running on dynamsoft.com: encode any text into 13 barcode symbologies and download the symbols as a PNG — or generate a stress-test dataset of degraded barcode images with ground-truth annotations, and benchmark a reader against it. Everything runs in your browser.
Randomize values encodes a fresh sample value of the selected symbology in every cell; Random types picks a random symbology per cell. Both leave the text field untouched. The grid is limited to 6 rows and 6 columns.
Generating…
Upload the downloaded PNG to the online barcode scanner — it reports the decoded text, the symbology, the bounding box and the decoding time.
Build a set of barcode images with known difficulty and known expected results. The seed drives every random choice — payloads, symbologies, placements and degradation values — so the same seed rebuilds the same test cases.
| On | Degradation | Min | Max | Unit |
|---|
A row with equal Min and Max applies that exact value to every image; a range varies it. Editing any value switches the preset to Custom. Hover a row for what the two numbers mean.
The preview is one image of the set, exactly as it is exported — no cell borders and no value captions, because a real capture does not have them. The table is the ground truth for that image: a reader that returns all of these values decoded everything.
| # | Symbology | Expected value | Visible |
|---|
The dataset is one ZIP: the images, plus annotations.json in the
barcode-benchmark/1.0 schema — the expected text, the symbology and the
four corner points of every symbol, in the coordinates of the exported image.
Drop the ZIP into the
online barcode scanner
and its benchmark reports how many of the expected values were decoded.
Images are always written as PNG, so the exported file does not add a second round of compression on top of the JPEG artifacts the preset simulates. The benchmark also uses the per-image degradation values in the annotations, so a miss can be read against the conditions that caused it.
| Symbology | Kind | Input |
|---|---|---|
| QR Code | 2D | Any text or URL. Error correction is applied automatically, so the symbol still decodes when part of it is damaged. |
| Data Matrix | 2D | Any text. The compact square symbol used on small parts and labels. |
| PDF417 | 2D | Any text. A stacked linear symbol, the format used on AAMVA driver licenses and many ID documents. |
| Aztec Code | 2D | Any text. Needs no quiet zone around the symbol. |
| MaxiCode | 2D | Up to 93 characters. A fixed-size hexagonal grid, originally designed for parcel sorting. |
| DotCode | 2D | Any text. A dot pattern that tolerates high-speed inkjet printing on curved surfaces. |
| EAN-13 | 1D | 12 digits — the 13th is the check digit and is calculated for you. A 13-digit value is accepted when its check digit is correct. |
| Code 128 | 1D | Any ASCII text. The densest common linear symbology. |
| Code 39 | 1D | Digits, capital letters, spaces and - . $ / + %. Lowercase letters are
rejected. |
| ITF | 1D | Digits. An odd count is padded with a leading zero, which is what the standard prescribes. |
| MSI | 1D | Digits. A Mod-10 check digit is appended, which is what readers expect to find; it comes back as the last character of the decoded text. |
| Pharmacode | 1D | A single number from 3 to 131070. Used on pharmaceutical packaging. |
| Codabar | 1D | Digits and - $ : / . +, wrapped in the start and stop characters
A, B, C or D — for example
A1234567890B. |
This page is a raw symbology encoder: whatever you type is written into the symbol as-is, with no application-layer structure. It does not build GS1 element strings, AAMVA payloads, vCards or label layouts — so it is the right tool for producing test symbols for a reader, and the wrong tool for producing a compliant shipping label. For a generator that does assemble a structured payload, see the driver license generator, which writes AAMVA PDF417 barcodes.
All 13 symbologies are produced by bwip-js, the JavaScript port of BWIPP. Barcodes are drawn on an
HTML5 canvas at a module scale wide enough to survive a re-upload or a printout: the exported
PNG is rendered at the natural symbol size, and Download PNG saves that canvas
1:1, so you can drop it straight into a document or a scanner test.
A long payload makes a wide symbol — a 120-character Code 128 is over 1300 px across even at the smallest module scale. Rather than shrinking the finished image (which would blur the bars), any oversized symbol is re-rendered at the largest whole-number module scale that fits, so the exported PNG keeps crisp, evenly spaced bars at any grid size.
Nothing you type leaves the browser: the page has no upload, no server call and no storage. Keep test payloads synthetic — a barcode is not a secret, and anyone with a phone can read what you put in it.
A stress image is synthesised, not photographed. The degradations model what a capture does to pixels — defocus, motion, JPEG, glare, perspective — but a synthetic blur is cleaner than a real lens and a synthetic glare has no colour fringing. Treat the numbers as a comparison between readers on identical inputs, not as a prediction of a specific camera.
Symbols are re-encoded at an integer module size rather than scaled down, so a hard image has fewer real pixels per module instead of blurred ones. Below roughly 1.5 px per module the symbol is past what a camera would resolve, and the preview says so: at that point a miss is expected and says nothing about the decoder.
The expected value is what the symbol decodes to, not what was typed in. EAN-13 gains a check digit and MSI gains a Mod-10 digit, so the annotation carries the longer number a decoder returns; an ITF payload is generated with an even digit count so no padding is applied; and a Codabar decoder strips the start and stop characters, so only the inner digits are expected — an expected value the encoder never produced would make a correct reader look wrong.
Every expected symbol is whole. A cut barcode cannot be decoded by any
reader, so counting one as a miss would measure nothing — and unlike a photograph, this
generator chooses where to put the frame. The crop therefore trims the empty border the
scene leaves around its symbols and stops before the edge would cut into one, which is
why a loosely framed image crops a lot and a tightly framed one hardly at all. The value
actually used is recorded as crop in the annotations, with the request beside
it as crop_requested.
The per-image degradation values are recorded in the annotations, so a miss can be read against the condition that caused it.
1D symbols are rendered without human-readable text. The text sits under the bars, and the expected corner points would then include a region that no reader reports, which would make the box-overlap figure meaningless. The bars are what the test measures.