^XA
^FO0,90^AD^BY3
^BCN,100,Y,N,Y,A
^MD10
^FD1458622235534^FS
^XZ
Using Label Viewer I was able to play around with ZPL and after reading some documentation figured out that ^FO0,90 is what positions the barcode. 0 is for the number of dots from the left and 90 is for the number of dots from the top.
My question is, how can the width of the above bar code be calcuated in dots? If I know the width of the barcode, I can then center it programmatically.
The printer's resolution is 203dpi and given a 3' (width) x 2' (length) tag, that is 610 dots across.
What is the formula to calculate the width of a ZPL Barcode?
The Code 128 barcode includes three modes. The "A" in your ^BC means that the barcode algorithm will automatically select the best mode based on the placement of where the letters are mixed in with the numbers, and/or how many numbers are in a row. This results in barcodes that vary in length depending on their content.
You can change that A to an N. This will make the width easy to estimate, even if it's not the most space efficient.
For the N option: count 106 dots, total, for the bookends, and 33 dots for each digit.
For the N + Subset C option: If you can say for sure that you will always have an even number of digits (no letters, spaces, or other symbols). You can force the barcode into subset C mode. Count 104 dots for the bookends, and 33 dots for every two digits. But you must have an even number of digits.
^BCN,100,Y,N,Y,N
^FD>;1422335544^FS
The >; tells ZPL to render this as subset C.
If you know that you will need to support alphanumeric barcodes, then stick with the A. This is where things get harder.
You will need to model the barcode algorithm in your programming language of choice. Perhaps you could find an existing library, as Code 128 is a very popular barcode. Use the library to render the barcode in memory. You may have to play with the parameters to get it to produce a barcode equal to your ZPL output. Then have your program use the output of the library to determine the width of the barcode.
If your barcode is always going to be 13 digits, then automatic centering is a moot point. The barcode will always be the same width, even in automatic mode. Find the ^FO that looks like it's centered on the label, and stick with that. This barcode is 368 dots wide. Try ^FO121,90.
I didn't calculate the width of the barcode, I measured it by rendering the label to a Gif and then examining the label in a paint program that would let me count the dots.
I suggest you have a look at the Code 128 wikipedia article for the details.
The natural unit of length for code 128 is the narrow bar width noted x (in your ZPL code set to 3 dots). A code 128 barcode (excluding the two 10x quiet zones) is made up of
a start character (11x wide)
n encoded character of width 11x
a CRC (11x wide)
a stop character (12x wide)
If your data takes n encoded characters, the length of the barcode is (34 + n*11)x. In your case, x is 3 dots, so at 8dot/mm the barcode will be (12.75 + n*4.125)mm wide.
You have to look into the encoding to figure out n. Minimal encodings are not unique, but in your case the data will be encoded with 8 barcode characters: 6 code C character (for 6 pairs of digits), 1 switch code character and 1 code A character (for the last digit). The barcode should be 45.75mm / 366dot wide.
There is a little issue with your ZPL. You specified a UCC checkcode on a non UCC barcode. I am not familiar with UCC/GS1-128 barcodes but that might introduce extra barcode characters or be irrelevant.
Also you might consider padding your timestamp with a leading 0. With Code 128, pairs of digit have a better encoding. A 14-digit barcode will be be 4.125mm shorter.
I just mentionned the quiet zone, barcode readers require them.
Related
I have strings that are mostly standard alpha-numeric and other printable ASCII characters, and would like to display these in a console window on Windows. What I'm looking for is either a console font or a unicode set of characters that represent the numbers 0-255 (0-FF) using a single glyph for each. The thing that comes closest that I am aware of is that unicode has a small set of circled numbers, 1-20, and elsewhere numbers 21-50. Something along those lines, but for 0-255 (or 0-FF) is what I'm trying to find.
It seems to me that this would be a relatively common need/desire, but I've been unable to track down a solution. Any help appreciated!
The C0 and C1 controls can be represented by control pictures. The rest of the C0 Controls and Basic Latin, and C1 Controls and Latin-1 Supplement blocks can be represented by themselves. You may have to test a few fonts to find one that supports all these characters.
However, you said "ASCII" and "0-255". But, ASCII has only 128 codepoints. Your codepoints 128-255 must be from an unnamed character set. Although you probably mean one of the well-known ones, they are so numerous that a detailed answer isn't practical.
There is also the Unicode BMP Fallback SIL font that covers U+0000 to U+FFFF (but not U+10000 to U+10FFFF).
The barcode is found on the clear side of some CDs and DVDs (all of them bearing "DADC", "Sony DADC" or "Sony Music" somewhere on the ring)
There are only two widths and they are always in the configuration 1,2 or 2,1. I'll treat these as binary 0 and 1 from now on.
The data seems to be aligned in four bits, with 0x0 to 0x9 representing numbers 0-9 and some sort of encoding for other characters (for example 0xb0 produces 'A' and 0xd6 produces '-').
It seems like 0xa begins a text mode sequence, 0xe begins some different mode sequence (some of it seems to be a checksum) and 0xf ends it.
a few examples in hexadecimal, with corresponding human-readable text version from the ring after whitespace:
ab00100199443d60101e8085f A0100199443-0101
ab00100343510d60101e9880f A0100343510-0101
ab00100993638d6b0911e29420f A0100993638-A911
ab00100993638d6b1911e29421f A0100993638-B911
ac85107702000d60101e5688f S5107702000-0101
ac85107642000d60101e5388f S5107642000-0101
ab00100779256d6b0511e28211f A0100779256-A511
a32d6475824d610e6094f 32-475824-10
ab00100490591d6b0511e26302f A0100490591-A511
There may be errors, I decoded them by hand.
The only example I found with the barcode visible from the label side, resulting in a clear scan (the first example):
convert XiOSq.jpg -resize 314% -distort DePolar 0 -gravity southeast -crop 53x10% +repage -resize 100x16%\! output.jpg:
The shorter barcode, present on CDs (e6b007f in this example), is a mystery.
clean version of the first example:
(the 314% and 16% are just approximations of 100pi and 50/pi, to make the outer edge of the circle the same length, and the width of the ring match between the images; 53% is the percentage of the circle elapsed clockwise from the top to just after the "DADC" logo, and 10% is the percentage [from the outer edge of the circle to the middle] which I wanted to be the top of the output image; south = outer edge; east = clockwise)
Google for 'CD Matrix'
Until now I can't see any practical use for the consumer. Most barcode reader I'm working with even can't read the round barcode (it's a nice use of convert in your post!).
Maybe it is a kind of early 'genuine product' label (like the holographic pictures) to prevent music-piracy in pre-mp3 times.
Source:
https://www.discogs.com/help/submission-guidelines-release-format.html#CD_Matrix
https://www.discogs.com/help/submission-guidelines-release-barcode.html
Apologies for necro-ing this post, but the folks over on the Redump Forums cracked this custom encoding a little while back.
The encoding is a combination of 4-bit BCD for integers and a custom hex-encoding for characters, which can be viewed in the post linked above.
I created a decoder for this encoding while trying to find the same thing, which can be found here. It's very basic and incredibly messy, but it accepts the raw binary of a barcode and outputs a decoded string.
I want to read a barcode from a scanned image that I printed. The image format is not relevant. I found that the scanned images are of very low quality and can understand why it normal barcodes fail.
My idea is to create a non standard and very simple barcode at the top of each page printed. It will be 20 squares in a row forming a simple binary code.Filled = 1, open = 0. It will be large enough on aA4 to make detection easy.
At this stage I need to load the image and find the barcode somewhere at the top. It will not be exactly at the same spot as it is scanned in. Step into each block and build the ID.
Any knowledge or links to info would be awesome.
If you can preset a region of interest that contains the code and nothing else, then detection is pretty easy. Scan a few rays across this region and find the white/black and black/white transitions. Then, knowing where the "cells" should be, you known their polarity.
For this to work, you need to frame your cells with two black ones on both ends to make sure to know where it starts/stops (if the scale is fixed, you can do with just a start cell, but I would not recommend this).
You could have a look at https://github.com/zxing/zxing. I would suggest to use a 1D bar code, but wide enough to match the low resolution of the scanner.
You could also invent your own bar code encoding and try to parse it your self. Use thick bars for 1 and thin lines for 0. A thick bar would be for instance 2 white pixels, 4 black pixels. A thin line would be 2 white pixels, 2 black pixels and 2 white pixels. The last two pixels encode the bit value.
The pixel should be the size of the scanned image pixel.
You then process the image scan line by scan line, trying to locate the bar code.
We locate the bar code by comparing a given pixel value sequence with a pattern. This is performed by computing a score function. The sum of squared difference is a good pick. When computing the score we ignore the two pixels encoding the bit value.
When the score is below a threshold, we found a matching pattern. It is good to add parity bits to the encoded value so that it's validity can be checked.
Computing a sum of square on a sliding window can be optimized.
GetTextExtent32 returns different character width ratios (e.g., width of '9' versus space) than Word or Acrobat use when displaying the same font (e.g., 10-point Arial).
This matters because I'm trying to prepare clipboard strings that will get pasted into apps that don't support much formatting (no tabs or tables), but I still need to align certain columns of info. I'm trying to overcome this challenge by dynamically calculating the number of spaces I need to insert (remember, no tabs allowed!).
For example, calling GetTextExtent32 with a selected font of Arial 10-point gives a logical unit width of 7 for the digit '9', and a logical unit width of 4 for a space. This ratio proves correct when using something like DrawText.
However, when I export strings to Word or Acrobat, it turns out that 2 spaces in this example font exactly equals the width of one 9 (whether looking at a single 9, or nine contiguous 9s). I don't know much about fonts, but it doesn't appear to be any kind of juxtaposition issue; GetCharABCWidths shows 0 for both the a and c widths.
Does anyone know why Word and Acrobat are not showing the same proportions/measurements for a given font as Windows itself? Is there are a way to calculate this?
I have to display barcodes on a mobile screen which can only be within 72x28 pixels (in an area of around 1.5cmx0.5cm). I then have to scan those barcodes using a smartphone. I don't have to encode a lot of information - only enough that can be efficiently decoded in this scenario. What is the best poosible barcode encoding to use? I think given that the vertical is very small, 1D barcodes would be better, but I am not bale to figure out the encoding out of all the available options.
The smallest QR code, Version 1, takes 21x21 pixels. Really, the QR codes are supposed to have a 4-module border on all sides, which would technically make it 29x29 at least. However in practice, leaving one pixel off will probably be just fine, letting you fit into 29x28.
Version 1 can encode up to 41 digits in numeric mode, with the lowest EC level, L.
For 5 digits, a simple Code 128 1D barcode is perhaps an even better choice.