7

我正在使用 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 的示例

DataMatrix条码App截图

更新 这就是我将位矩阵转换为位图的方式

    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 hintMap = 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 中的一个错误。我不明白为什么如果我改变大小,生成不起作用。

4

4 回答 4

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);
于 2014-04-02T20:16:06.590 回答
3

我记得,Data Matrix 编码器有点奇怪,因为代码来自不同的地方(barcode4j)。它将使用最小的适当尺寸并假定调用者将根据需要缩放图形。

您可以在此处执行此操作 - 只需将 设置ImageView为缩放其内容。只要您不启用抗锯齿功能,这对任何编码的条形码都不会造成伤害。

还有一个EncodeHintType.MIN_SIZE提示将设置最小大小,仅适用于 Data Matrix。

于 2014-03-31T16:31:46.223 回答
0

有没有一种简单的方法可以以某种方式缩放位矩阵?

就在这里。问题是使用 Android 自动缩放会遇到一些问题:

  1. Android 在缩放时使用双线性过滤
  2. 使用硬件加速时不能禁用双线性过滤

我采用的方法是通过位图的整数因子手动缩放。以下是将 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;
}
于 2015-11-20T17:01:54.207 回答
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 为 nil,因此您需要指定从 10 到 144 的维度。

在此处输入图像描述

或者!!或指定形状:

ZXDataMatrixSymbolShapeHintForceSquare
ZXDataMatrixSymbolShapeHintForceRectangle

于 2015-10-16T15:37:12.083 回答