LaravelPackages.net
Acme Inc.
Toggle sidebar
milon/barcode

Barcode generator like Qr Code, PDF417, C39, C39+, C39E, C39E+, C93, S25, S25+, I25, I25+, C128, C128A, C128B, C128C, 2-Digits UPC-Based Extention, 5-Digits UPC-Based Extention, EAN 8, EAN 13, UPC-A, UPC-E, MSI (Variation of Plessey code)

16.410.731
1.481
v13.5.1
About milon/barcode

milon/barcode is a Laravel package for barcode generator like qr code, pdf417, c39, c39+, c39e, c39e+, c93, s25, s25+, i25, i25+, c128, c128a, c128b, c128c, 2-digits upc-based extention, 5-digits upc-based extention, ean 8, ean 13, upc-a, upc-e, msi (variation of plessey code). It currently has 1.481 GitHub stars and 16.410.731 downloads on Packagist (latest version v13.5.1). Install it with composer require milon/barcode. Discover more Laravel packages by milon or browse all Laravel packages to compare alternatives.

Last updated

Packagist Downloads Stable version License Tests

Banner

Barcode generation for Laravel and plain PHP. This package wraps the TCPDF barcode engines (1D + QR / Data Matrix / PDF417) behind a small API that returns SVG, HTML, PNG, and JPEG.

Requires the PHP GD extension (ext-gd).

Full docs: oss.milon.im/barcode

Examples below are real outputs from this library. Regenerate them with:

php docs/generate-examples.php

Installation

composer require milon/barcode

Laravel compatibility

| Laravel | Package | |---------|---------| | 13.* | ^13.0 | | 12.* | ^12.0 | | 11.* | ^11.0 | | 10.* | ^10.0 | | 9.* | ^9.0 | | 8.* | ^8.0 | | 7.* | ^7.0 | | 6.* | ^6.0 | | 5.0–5.1 | ^5.1 | | 4.x | ^4.2 |

Laravel 6+ auto-discovers the service provider and facades (DNS1D, DNS2D).

Publish config (optional)

php artisan vendor:publish --provider="Milon\Barcode\BarcodeServiceProvider"

Default store path is the Laravel storage directory (used by *Path helpers). Ensure the directory is writable.


Quick start

use DNS1D;
use DNS2D;

// SVG / HTML (ready to echo)
echo DNS1D::getBarcodeSVG('CODE39DEMO', 'C39');
echo DNS2D::getBarcodeHTML('https://example.com', 'QRCODE');

// PNG / JPEG as base64 (use the data URI form)
echo '<img src="data:image/png;base64,' . DNS1D::getBarcodePNG('CODE39DEMO', 'C39') . '" alt="barcode">';
echo '<img src="data:image/png;base64,' . DNS2D::getBarcodePNG('https://example.com', 'QRCODE') . '" alt="qr">';

Blade

Always use {!! !!} (unescaped). PNG helpers return raw base64, not a full data: URL:

{!! DNS1D::getBarcodeHTML('5901234123457', 'EAN13') !!}

<img
  src="data:image/png;base64,{{ DNS2D::getBarcodePNG($url, 'QRCODE', 6, 6, [0,0,0], [255,255,255]) }}"
  alt="QR code"
>

Units: $w and $h

| API | $w | $h | |-----|------|------| | DNS1D (1D) | Width of a single bar in pixels | Total barcode height in pixels | | DNS2D (QR / DM / PDF417) | Width of a module in pixels | Height of a module in pixels |

Larger $w / $h = larger image. Typical starting points:

  • 1D labels: $w = 2–3, $h = 50–80
  • QR for screen: $w = $h = 4–8
  • QR for print: $w = $h = 8–12

Output methods

| Method | Returns | |--------|---------| | getBarcodeSVG(...) | SVG markup string | | getBarcodeHTML(...) | HTML (div/span) markup | | getBarcodePNG(...) | Base64-encoded PNG | | getBarcodeJPG(...) | Base64-encoded JPEG (1D) | | getBarcodePNGPath(...) | Relative path to a PNG written under the store path | | getBarcodeJPGPath(...) | Relative path to a JPEG written under the store path (1D) |

Common options

1D (DNS1D)

getBarcodePNG($code, $type, $w = 2, $h = 30, $color = [0,0,0], $showCode = false, $bgcolor = null)
getBarcodePNGPath($code, $type, $w = 2, $h = 30, $color = [0,0,0], $showCode = false, $bgcolor = null, $filename = null)

2D (DNS2D)

getBarcodePNG($code, $type, $w = 3, $h = 3, $color = [0,0,0], $bgcolor = null)
getBarcodePNGPath($code, $type, $w = 3, $h = 3, $color = [0,0,0], $bgcolor = null, $filename = null)
  • $color — RGB foreground [r, g, b] (SVG/HTML use CSS color strings)
  • $showCode — print human-readable text under 1D bars
  • $bgcolor — RGB background, or null for transparent (default)
  • $filename — optional custom file name for *Path helpers (extension optional; path segments are stripped)
// Custom file name → storage/.../product-42.png
DNS2D::getBarcodePNGPath($url, 'QRCODE', 6, 6, [0, 0, 0], [255, 255, 255], 'product-42');

Quiet zone (padding) for print / scanners

Printed barcodes often fail to scan when bars sit flush against the page edge or other graphics. Add a quiet zone with setPadding() (pixels on every side):

CODE 128 with quiet-zone padding

// ~10× bar width is a common 1D rule of thumb ($w = 2 → padding 20)
DNS1D::setPadding(20);
echo DNS1D::getBarcodeSVG($code, 'C128', 2, 80);

DNS2D::setPadding(4 * 6); // ~4 modules around a QR with $w = 6
echo '<img src="data:image/png;base64,' . DNS2D::getBarcodePNG($url, 'QRCODE', 6, 6, [0, 0, 0], [255, 255, 255]) . '">';

DNS1D::setPadding(0); // reset (instances/facades keep the value until changed)

SVG output also sets shape-rendering="crispEdges" to reduce print-time anti-alias blur.

QR logo (centered)

Overlay a logo on QR / Datamatrix PNG output (GD). Use high error correction (QRCODE,H) and keep the logo modest (~15–25% of width) so scanners still read the code.

QR code with centered logo

DNS2D::setLogo(storage_path('app/logo.png'), 0.2);
echo '<img src="data:image/png;base64,' .
    DNS2D::getBarcodePNG($url, 'QRCODE,H', 6, 6, [0, 0, 0], [255, 255, 255]) .
    '">';
DNS2D::setLogo(null); // clear

Retail UPC-A / EAN layout

EAN-8, EAN-13, UPC-A, and UPC-E now use taller guard bars and, when $showCode is enabled, split human-readable digits (number system / left / right / check) instead of one centered string.

UPC-A retail layout

echo '<img src="data:image/png;base64,' .
    DNS1D::getBarcodePNG('042100005264', 'UPCA', 3, 90, [0, 0, 0], true, [255, 255, 255]) .
    '">';

Background color (dark UI / email)

Transparent PNGs disappear on dark backgrounds. Pass a white (or light) $bgcolor:

| Transparent (default) | White background | |-----------------------|------------------| | Transparent QR | QR on white |

// Recommended for dark themes and email clients
DNS2D::getBarcodePNG($url, 'QRCODE', 6, 6, [0, 0, 0], [255, 255, 255]);

DNS1D::getBarcodePNG('WHITEBG', 'C128', 3, 70, [0, 0, 0], false, [255, 255, 255]);

CODE 128 with white background


Examples (with screenshots)

CODE 39

CODE 39

DNS1D::getBarcodePNG('CODE39DEMO', 'C39', 3, 80, [0, 0, 0], true, [255, 255, 255]);

CODE 39+

CODE 39+

DNS1D::getBarcodePNG('CODE39', 'C39+', 3, 80, [0, 0, 0], true, [255, 255, 255]);

CODE 128

CODE 128

DNS1D::getBarcodePNG('Code128Demo', 'C128', 3, 80, [0, 0, 0], true, [255, 255, 255]);

CODE 128A / 128B / 128C

| C128A | C128B | C128C | |-------|-------|-------| | C128A | C128B | C128C |

DNS1D::getBarcodePNG('CODE128A', 'C128A', 3, 80, [0, 0, 0], true, [255, 255, 255]);
DNS1D::getBarcodePNG('Code128B', 'C128B', 3, 80, [0, 0, 0], true, [255, 255, 255]);
DNS1D::getBarcodePNG('12345678', 'C128C', 3, 80, [0, 0, 0], true, [255, 255, 255]); // digits, even length

EAN-13 / EAN-8 / UPC-A

| EAN-13 | EAN-8 | UPC-A | |--------|-------|-------| | EAN-13 | EAN-8 | UPC-A |

DNS1D::getBarcodePNG('5901234123457', 'EAN13', 3, 80, [0, 0, 0], true, [255, 255, 255]);
DNS1D::getBarcodePNG('96385074', 'EAN8', 3, 80, [0, 0, 0], true, [255, 255, 255]);
DNS1D::getBarcodePNG('042100005264', 'UPCA', 3, 80, [0, 0, 0], true, [255, 255, 255]);

Interleaved 2 of 5 / Codabar / Pharmacode

| I25 | Codabar | Pharmacode | |-----|---------|------------| | I25 | Codabar | Pharmacode |

DNS1D::getBarcodePNG('12345670', 'I25', 3, 80, [0, 0, 0], true, [255, 255, 255]);
DNS1D::getBarcodePNG('A123456A', 'CODABAR', 3, 80, [0, 0, 0], true, [255, 255, 255]);
DNS1D::getBarcodePNG('123456', 'PHARMA', 3, 80, [0, 0, 0], true, [255, 255, 255]);

Custom bar color

Green CODE 39

DNS1D::getBarcodePNG('GREENDEMO', 'C39', 3, 80, [0, 128, 0], true, [255, 255, 255]);

QR Code / Data Matrix / PDF417

| QR Code | Data Matrix | PDF417 | |---------|-------------|--------| | QR | Data Matrix | PDF417 |

DNS2D::getBarcodePNG('https://milon.im', 'QRCODE', 6, 6, [0, 0, 0], [255, 255, 255]);
DNS2D::getBarcodePNG('DM-DEMO-12345', 'DATAMATRIX', 6, 6, [0, 0, 0], [255, 255, 255]);
DNS2D::getBarcodePNG('PDF417 Demo Payload', 'PDF417', 3, 3, [0, 0, 0], [255, 255, 255]);

Browse all generated samples: docs/examples/gallery.html

Regenerate images + gallery:

php docs/generate-examples.php

Symbology character sets

Invalid input throws Milon\Barcode\InvalidBarcodeException with a hint for the chosen type.

| Type | Allowed data (practical) | |------|--------------------------| | C39 | 0-9 A-Z space and -.$/+% | | C39E / C39E+ | Full ASCII (extended CODE 39) | | C128 | Full ASCII; auto code-set | | C128A | Uppercase / control; no lowercase — use C128B or C128 | | C128B | Full ASCII | | C128C | Digits only, encoded in pairs (even length) | | EAN13 | 12–13 digits (check digit calculated/validated) | | EAN8 | 7–8 digits | | UPCA | 11–12 digits | | UPCE | Compressed UPC-E digit form | | I25 / S25 | Digits (I25 prefers even length) | | CODABAR | Digits plus -$:/.+ with A–D start/stop | | PHARMA | Numeric pharmacode | | QRCODE | Text/URL; capacity depends on version/ECC | | DATAMATRIX | Text; capacity depends on symbol size | | PDF417 | Longer text payloads |

Prefer C128 (auto) unless you specifically need A/B/C.

Also supported (1D)

C39+, C93, S25, S25+, I25+, GS1-128, EAN2, EAN5, MSI, MSI+, POSTNET, PLANET, RMS4CC, KIX, IMB, CODE11, PHARMA2T


Standalone PHP (no Laravel)

Laravel is optional. Without a container, the store path defaults to the system temp directory (or whatever you set):

use Milon\Barcode\DNS1D;
use Milon\Barcode\DNS2D;

$d1 = new DNS1D();
$d1->setStorPath(__DIR__ . '/cache/');

echo $d1->getBarcodeHTML('9780691147727', 'EAN13');
echo '<img src="data:image/png;base64,' . $d1->getBarcodePNG('9780691147727', 'EAN13') . '">';

$d2 = new DNS2D();
$d2->setStorPath(__DIR__ . '/cache/');
file_put_contents(
    __DIR__ . '/cache/qr.png',
    base64_decode($d2->getBarcodePNG('https://example.com', 'QRCODE', 6, 6, [0, 0, 0], [255, 255, 255]))
);

Use the instance API (or the Laravel facade). Calling DNS2D::getBarcodePNG() as a static method on the class itself will not work.


FAQ

Why is my Blade barcode empty / escaped HTML?
Use {!! DNS1D::getBarcodeHTML(...) !!}, not {{ }}.

Why is the <img> broken?
PNG helpers return base64 only. Prefix with data:image/png;base64,.

Barcode works in light mode but not dark mode / email?
Pass a solid $bgcolor, e.g. [255, 255, 255].

Printed barcode won’t scan reliably?
Add a quiet zone (setPadding(...)), use a larger $w (avoid $w = 1 for print), and prefer SVG/PNG over scaled-down screen captures. See Quiet zone.

InvalidBarcodeException?
The payload does not match the symbology (see table above). Switch type or sanitize input.

Can this package scan barcodes from a camera?
No. It only generates barcodes. Scanning needs a separate library or device SDK.

Can it authenticate users / replace login?
No. Generating a QR of a URL or token is not authentication by itself.


License

GNU LGPLv3. Copyright Nuruzzaman Milon. Original barcode classes by Nicola Asuni / Tecnick.com LTD (TCPDF).

Buy me a coffee

Comments