I am trying to generate a Code128 barcode using Zxing:
try {
int width = (int) (barcode.getWidth() * 0.95f);
int height = (int) (width * 0.2f);
BitMatrix bitMatrix = writer.encode(code.number, BarcodeFormat.CODE_128, width, height);
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
bitmap.setPixel(i, j, bitMatrix.get(i, j) ? Color.BLACK : Color.WHITE);
}
}
barcode.setImageBitmap(bitmap);
} catch (WriterException e) {
e.printStackTrace();
}
Where barcode
is an ImageView
, whose width is set to match_parent
(with 5dp margin) and height is wrap_content
. The image I am generating has an aspect ratio of 5:1, and I expected the black stripes to appear in the very beginning of the image, and finish at the very end.
This is what happens, though:
The ImageView
has the green background (note that the image width is 95% of the ImageView
width), and the white part belongs to the image. As you can see, there's a huge white area, maybe 40% of the image.
The question is why does the stripes not fill the full (or most of the) width I specified on the writer.encode()
method? How can I force this to happen?
Update:
Using different values for the scale type, I noticed that the white margin is present only on the sides of the barcode, and never above or below it.
The bars in the barcode have to have widths that are an integer number of pixels, or else you'd get some distortions. The barcode is as wide as it can be satisfying these constraints.
A good solution for this use case is to set the width to 1. This will force the image to be as small as possible; narrow bars will be one pixel. Then you can let Android scale it exactly as you like.
This is not the most generic answer, but that's how I solved it:
My code uses Code128 standard, where each symbol is a combination of 11 stripes (either black or white. The code also has a fixed length, 20 characters. So I forced the writer
to encode using a width of 20 * 11
pixels. That did work, the the quiet zone around the code was minimal.
For the scaling purpose, however, that width was not good enough. Depending on the screen, the image would not be scaled in a good way, distorting the stripes in a non-even way, making the code unreadable. Then I choose to oversample the image, using this time 20 * 11 * 4
pixels. The results were much better, because now the image is being scaled down, and not up as before.
The oversample factor may vary depending on the dimension you need to display, but if you're in a similar situation, with fixed length of the barcode and each symbol, this is an easy way to get a nice barcode with minimal quiet zone and does not involve any further image processing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With