DataMatrix coding with zxing only generates a 14px bitmap

I use zxing to create barcodes with different types (EAN, 2of5 and DataMatrix). Generation generally works fine. The only problem I'm currently facing is that zxing only generates a 14x14 pixel bitmap, which is too small. But only when using DataMatrix! EAN13, 2of5 / ITF and QR codes work with the same code.

My code is:

BitMatrix bitMatrix = new DataMatrixWriter().encode(message, BarcodeFormat.DATA_MATRIX, 1080, 1080, null); int height = bitMatrix.getHeight(); //height is always 14, it doesn't matter what value I pass to the encoder 

As you can imagine, this looks pretty crap on a 1080p screen such as link 5. Am I getting something wrong? Do I need to make some special settings for DataMatrix?

Google and Stackoverflow could not help me since I cannot find examples of using DataMatrix

App screenshot of DataMatrix barcode

Update Here's how I convert bitmaps to bitmaps

  int width = bitMatrix.getWidth(); int height = bitMatrix.getHeight(); int[] pixels = new int[width * height]; // All are 0, or black, by default for (int y = 0; y < height; y++) { int offset = y * width; for (int x = 0; x < width; x++) { pixels[offset + x] = bitMatrix.get(x, y) ? BLACK : WHITE; } } Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); bitmap.setPixels(pixels, 0, width, 0, 0, width, height); 

If I use any other values ​​for height, I get an OutOfBoundsException, which is pretty obvious (I did not expect anything) ...

When I try to scale the image and set a fixed width and height, the barcode is scanned but looks like crap. This is also obvious, since the bit matrix is ​​only 14x14 instead of the size I specified.

enter image description here

Is there an easy way to scale the bit matrix somehow? Because it consists only of points, therefore it should be possible, but I do not want to calculate it myself. I could not find any documentation for bitmatrix except stackoverflow, and that didn't help me at all.

If I pass MinWidth or MaxWidth to the encoder via HintMap, the application always crashes with an Exception. HintMap (mWidth is the width of the device screen, but I tried several values): Hint Hashtable = new Hashtable ();

 hintMap.put(EncodeHintType.MIN_SIZE, new Dimension(mWidth, mWidth)); hintMap.put(EncodeHintType.MAX_SIZE, new Dimension(mWidth, mWidth)); hintMap.put(EncodeHintType.DATA_MATRIX_SHAPE, SymbolShapeHint.FORCE_SQUARE); 

An exception:

 java.lang.IllegalArgumentException: Can't find a symbol arrangement that matches the message. Data codewords: 7 

This last issue seems to me a bug in zxing. I do not understand why the generation does not work if I change the size.

+6
source share
4 answers

Here is a small example of how you can change your method for converting from BitMatrix to Bitmap. The method scales BitMatrix.

 int BLACK = 0xFF000000; int WHITE = 0xFFFFFFFF; // change the values to your needs int requestedWidth = 300; int requestedHeight = 300; int width = bitMatrix.getWidth(); int height = bitMatrix.getHeight(); // calculating the scaling factor int pixelsize = requestedWidth/width; if (pixelsize > requestedHeight/height) { pixelsize = requestedHeight/height; } int[] pixels = new int[requestedWidth * requestedHeight]; // All are 0, or black, by default for (int y = 0; y < height; y++) { int offset = y * requestedWidth * pixelsize; // scaling pixel height for (int pixelsizeHeight = 0; pixelsizeHeight < pixelsize; pixelsizeHeight++, offset+=requestedWidth) { for (int x = 0; x < width; x++) { int color = bitMatrix.get(x, y) ? BLACK : WHITE; // scaling pixel width for (int pixelsizeWidth = 0; pixelsizeWidth < pixelsize; pixelsizeWidth++) { pixels[offset + x * pixelsize + pixelsizeWidth] = color; } } } } Bitmap bitmap = Bitmap.createBitmap(requestedWidth, requestedHeight, Bitmap.Config.ARGB_8888); bitmap.setPixels(pixels, 0, requestedWidth, 0, 0, requestedWidth, requestedHeight); // I could only test it with BufferedImage and a modified version of the zxing J2SE client // BufferedImage bitmap = new BufferedImage(requestedWidth, requestedHeight, BufferedImage.TYPE_INT_ARGB); // bitmap.getRaster().setDataElements(0, 0, requestedWidth, requestedHeight, pixels); 
+10
source

As I recall, the Data Matrix encoder is kind of a strange person, as the code came from a different place (barcode4j). He will use the minimum appropriate sizes and assumes that the caller will scale the schedule as desired.

You can do it here - just install ImageView to scale its contents. This should not damage any of the encoded barcodes if you do not activate anti-aliasing.

There is also a hint EncodeHintType.MIN_SIZE , which will set the minimum size, only for the data matrix.

+3
source

I know this question is about Android, but I believe that it can be classified as general. I work with Swift and the ZXingObjC shell. I get this error using DataMatrix encoding:

'Unable to find character layout matching message. Data Code Words: 5 '

So, debugging the code, I came to the ZXDataMatrixSymbolInfo class, by the method:

 + (ZXDataMatrixSymbolInfo *)lookup:(int)dataCodewords shape:(ZXDataMatrixSymbolShapeHint)shape minSize:(ZXDimension *)minSize 

When does this happen?

I am writing a custom swift shell (CoderEncoder) for my project using this method:

 static func encode(string code: String, encoding: CoderEncorderType, size: CGSize = CGSizeMake(200, 200)) -> UIImage? { let writer: ZXWriter = ZXMultiFormatWriter.writer() as! ZXWriter do { let format = CodeEncoder.getEncoding(type: encoding) let result = try writer.encode(code, format: format, width: Int32(size.width), height: Int32(size.height)) let cgImage = ZXImage(matrix: result, onColor: UIColor.blackColor().CGColor, offColor: UIColor.clearColor().CGColor).cgimage return UIImage(CGImage: cgImage) } catch let error as NSError { ERLog(what: error) } return nil } 

So when I call:

 CoderEncoder.encode("foo", .DataMatrix) 

an error occurs.

Basically, in ZXDataMatrixWriter maxSize is zero, so you need to specify a size from 10 to 144.

enter image description here

or!! or specify the form:

ZXDataMatrixSymbolShapeHintForceSquare
ZXDataMatrixSymbolShapeHintForceRectangle

0
source

Is there an easy way to scale the bit matrix somehow?

Yes there is. The problem is that using Android auto scaling leads to some problems:

The approach I made is manually scaling with an integer Bitmap coefficient. Here's how to convert BitMatrix to an unscaled bitmap:

  /** * Create an unscaled bitmap (1 square = 1 pixel) from a bitmatrix * * @param bitMatrix the bitmatrix to convert * @return a unscaled bitmap */ public Bitmap drawUnscaledBitmap(BitMatrix bitMatrix) { final int bmWidth = bitMatrix.getWidth(); final int bmHeight = bitMatrix.getHeight(); final Bitmap bitmap = Bitmap.createBitmap(bmWidth, bmHeight, Bitmap.Config.ARGB_8888); int[] pixels = new int[bmWidth * bmHeight]; for (int y = 0; y < bmHeight; y++) { int offset = y * bmWidth; for (int x = 0; x < bmWidth; x++) { pixels[offset + x] = bitMatrix.get(x, y) ? Color.BLACK : Color.WHITE; } } bitmap.setPixels(pixels, 0, bmWidth, 0, 0, bmWidth, bmHeight); return bitmap; } 

and here's how to scale the bitmap to (almost) to fit the size of the rectangle:

 /** * Upscale a bitmap (maintaining ratio) by the biggest integer scaling factor that allows the bitmap to still fit in the given size * * @param bitmap the bitmap to upscale * @param size the size that the output scaled bitmap needs to fit in * @return the scaled bitmap if the integer scaling factor is > 1; the original bitmap otherwise */ public Bitmap drawScaledBitmap(Bitmap bitmap, Size size) { final int bmWidth = bitmap.getWidth(); final int bmHeight = bitmap.getHeight(); final int wScalingFactor = size.getWidth() / bmWidth; final int hScalingFactor = size.getHeight() / bmHeight; final int scalingFactor = Math.min(wScalingFactor, hScalingFactor); return scalingFactor > 1 ? Bitmap.createScaledBitmap(bitmap, bmWidth * scalingFactor, bmHeight * scalingFactor, false) : bitmap; } 
0
source

All Articles