We are trying to generate correct EAN-128 codes for product labels, with TCPDF library, but our client says that the barcode scanner doesn't read the generated barcode. The original(old) barcode and string:
The code string is:
$codeString = "(01)08437013308045(3013)2675(15)161201(10)150518"
If we pass the string directly to the TCPDF function, like this:
$label->write1DBarcode($codeString, 'C128A', $x, $y, $w, $h);
we're getting correct output (which the scanner won't read) but the bars are more dense comparing to the original barcode which seems shorter and less dense (they say it's EAN-128):
We found here (EAN-128 with FNC1) that adding chr(241)
before the $codeString
should help but if we add it, the resulting image is stripped off of everything in human readable code:
Since we don't own a barcode reader, we can't check the errors ourselves.
What we are missing here? We're using TCPDF version 6.2.12.
There are a number of problems here that I'll work through.
Firstly, you have misread the text of the original barcode which contains the fixed-length Application Identifier (AI) field (3103)2775
representing net weight.
You have written a code containing (3013)2675
which is invalid. There is no AI (3013) and unfortunately this would prefix match with the legitimate AI (30) representing an item count which is a variable-length field. Therefore a decoder would continue to read the remaining data until the end of the code into AI (30) since there is no subsequent field terminator character (FNC1). That's a lot of items – more than eight digits worth in fact so the reader may indicate a fault!
The "extraction" part of this answer provides background on how GS1 data is encoding within a Code 128 barcode to produce a valid GS1-128 symbol.
Let's assume that you meant to encode the GS1 data (01)08437013308045(3103)2675(15)161201(10)150518
.
The raw data that you need to encode in the Code 128 is {FNC1}0108437013308045310326751516120110150518
.
This has been derived as follows:
[*] Note that the list of AIs provided in the GS1 General Specifications §3.2 "GS1 Application Identifiers in Numerical Order" indicates whether they require termination by an FNC1 character when followed by additional data.
How does this knowledge translate into code for TCPDF? I've never used it sorry, but this might be helpful:
Your $codeString
variable would need to be defined something like:
$codeString = chr(241).'0108437013308045310326751516120110150518';
This assumes that the linked to answer on the support forum is correct in stating that TCPDF uses ASCII ordinal 241 to indicate an FNC1 character. (There is some doubt whether this is the case.) If it works then this is a library-specific choice and you shouldn't read much into the fact that they have chosen value 241. See here for details about encoding non-data characters such as FNC1.
I also notice that you pass C128A
to the type
parameter of write1DBarcode
which limits the symbol to mode A (numbers, uppercase letters and control characters.) This would be terribly inefficient and is likely to result in a symbol that is too wide (or too dense when rescaled) to scan with most standard equipment used for logistics applications.
Code 128 supports a mode C that provides double-density compression of digits so you should use this, probably by passing type=C128C
or type=C128
(auto) assuming that TCPDF's auto-encoding is any good and future symbols that you will create may need to contain letters.
$label->write1DBarcode($codeString, 'C128', $x, $y, $w, $h);
As far as the human-readable text beneath the barcode is concerned, if this doesn't display correctly for properly encoded data then you may need to raise a bug report or feature request against TCPDF.