我使用zxing生成不同类型的条形码(EAN,2of5和DataMatrix)。生成一般工作正常。我目前唯一的问题是zxing只生成一个14x14像素的位图,这个位图太小了。但只有在使用DataMatrix时! EAN13,2of5 / ITF和QR码与相同的代码完美配合。
我的代码:
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
正如你可以想象的那样,在像nexus 5这样的1080p屏幕上看起来很糟糕。我错了吗?我是否必须为DataMatrix做一些特殊设置?
谷歌和Stackoverflow无法帮助我,因为我无法找到任何使用DataMatrix的例子
更新 这就是我将bitmatrix转换为位图的方法
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);
如果我对高度使用任何其他值,我会得到一个非常明显的OutOfBoundsException(我没有想到其他任何东西)......
当我尝试缩放图像视图并设置固定的宽度和高度时,条形码是可扫描的,但看起来像狗屎。这也是显而易见的,因为比特矩阵只有14x14而不是我指定的大小。
是否有一种简单的方法来以某种方式缩放比特矩阵?因为它只包含点,所以它应该是可能的,但我不想自己计算它。除了stackoverflow之外,我找不到任何关于bitmatrix的文档,这对我没什么帮助。
如果我通过HintMap将MinWidth或MaxWidth传递给编码器,应用程序总是会因异常而崩溃。 HintMap(mWidth是设备的显示宽度,但我尝试了几个值): 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);
例外:
java.lang.IllegalArgumentException: Can't find a symbol arrangement that matches the message. Data codewords: 7
这个最后一个问题在我看来就像zxing中的一个错误。我不明白为什么如果改变大小,生成不起作用。
答案 0 :(得分:11)
以下是一个小例子,您可以更改从BitMatrix到Bitmap的转换方法。该方法可以缩放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);
答案 1 :(得分:3)
我记得,Data Matrix编码器是一个奇怪的人,因为代码来自不同的地方(barcode4j)。它将使用最小的适当尺寸,并假定调用者将根据需要缩放图形。
您可以在此处执行此操作 - 只需设置ImageView
即可缩放其内容。只要您不启用抗锯齿,这对任何编码的条形码都不会有害。
还有一个EncodeHintType.MIN_SIZE
提示,它将设置最小尺寸,仅适用于Data Matrix。
答案 2 :(得分:0)
我知道这个问题是关于Android的,但我认为可以归类为通用 我正在使用Swift和包装器ZXingObjC。我使用DataMatrix编码获得此错误:
'无法找到与消息匹配的符号排列。数据 代码字:5'
所以,调试代码,我到了类ZXDataMatrixSymbolInfo,方法:
+ (ZXDataMatrixSymbolInfo *)lookup:(int)dataCodewords shape:(ZXDataMatrixSymbolShapeHint)shape minSize:(ZXDimension *)minSize
什么时候发生?
我使用这种方法为我的项目编写了一个自定义swift包装器(CoderEncoder):
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
}
所以,当我打电话时:
CoderEncoder.encode("foo", .DataMatrix)
发生错误。
基本上,在ZXDataMatrixWriter中,maxSize为零,因此您需要指定10到144之间的维度。
或!!或指定形状:
ZXDataMatrixSymbolShapeHintForceSquare
ZXDataMatrixSymbolShapeHintForceRectangle
答案 3 :(得分:0)
有没有一种简单的方法来缩放比特矩阵?
是的,有。问题是使用Android自动缩放会遇到一些问题:
我采用的方法是通过Bitmap的整数因子手动缩放。以下是将BitMatrix转换为未缩放的位图的方法:
/**
* 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;
}
以下是如何将位图放大到(几乎)适合所需的矩形大小:
/**
* 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;
}