【问题标题】:ZXing convert Bitmap to BinaryBitmapZXing 将 Bitmap 转换为 BinaryBitmap
【发布时间】:2013-02-13 19:34:26
【问题描述】:

我正在使用 OpenCV 和 Zxing,我想添加二维码扫描。我有几种类型的图像可以发送。可能最好的是 Bitmat(另一种选择是 OpenCV Mat)。

看起来你以前可以这样转换:

Bitmap frame = //this is the frame coming in

LuminanceSource source = new RGBLuminanceSource(frame);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

//then I can use reader.decode(bitmap) to decode the BinaryBitmap

但是,RGBLuminaceSource 看起来不再需要位图作为输入。那么我还能如何将输入图像转换为 BinaryBitmap ???

编辑:

好的,我相信我已经取得了一些进展,但我仍然遇到问题。我想我有将位图转换为正确格式的代码,但是我现在得到了一个 arrayIndexOutOfBounds

public void zxing(){
    Bitmap bMap = Bitmap.createBitmap(frame.width(), frame.height(), Bitmap.Config.ARGB_8888);
    Utils.matToBitmap(frame, bMap);
    byte[] array = BitmapToArray(bMap);
    LuminanceSource source = new PlanarYUVLuminanceSource(array, bMap.getWidth(), bMap.getHeight(), 0, 0, bMap.getWidth(), bMap.getHeight(), false);
        
    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
    Reader reader = new DataMatrixReader();
    String sResult = "";
    try {
        Result result = reader.decode(bitmap);
        sResult = result.getText();
        Log.i("Result", sResult);
        }
    catch (NotFoundException e) {
            Log.d(TAG, "Code Not Found");
            e.printStackTrace();
    }
}

public byte[] BitmapToArray(Bitmap bmp){
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.JPEG, 50, stream);
    byte[] byteArray = stream.toByteArray();
    return byteArray;
}

我得到了错误

02-14 10:19:27.469: E/AndroidRuntime(29736): java.lang.ArrayIndexOutOfBoundsException: length=33341; index=34560 02-14 10:19:27.469: E/AndroidRuntime(29736):   at 
com.google.zxing.common.HybridBinarizer.calculateBlackPoints(HybridBinarizer.java:199)

我已经记录了 byte[] 的大小,它就是上面显示的长度。我不明白为什么 zxing 期望它更大

【问题讨论】:

    标签: android zxing


    【解决方案1】:

    好的,我明白了。正如 Sean Owen 所说,PlanarYUVLuminaceSource 仅适用于默认的 android 相机格式,我猜 OpenCV 不会使用这种格式。简而言之,您可以这样做:

    //(note, mTwod is the CV Mat that contains my datamatrix code)
    
    Bitmap bMap = Bitmap.createBitmap(mTwod.width(), mTwod.height(), Bitmap.Config.ARGB_8888);
    Utils.matToBitmap(mTwod, bMap);
    int[] intArray = new int[bMap.getWidth()*bMap.getHeight()];  
    //copy pixel data from the Bitmap into the 'intArray' array  
    bMap.getPixels(intArray, 0, bMap.getWidth(), 0, 0, bMap.getWidth(), bMap.getHeight());  
    
    LuminanceSource source = new RGBLuminanceSource(bMap.getWidth(), bMap.getHeight(),intArray);
    
    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
    Reader reader = new DataMatrixReader();     
    //....doing the actually reading
    Result result = reader.decode(bitmap);
    

    就是这样,一点也不难。只需要将 Android 位图转换为整数数组,这就是小菜一碟。

    【讨论】:

      【解决方案2】:
      public static String readQRImage(Bitmap bMap) {
          String contents = null;
      
          int[] intArray = new int[bMap.getWidth()*bMap.getHeight()];  
          //copy pixel data from the Bitmap into the 'intArray' array  
          bMap.getPixels(intArray, 0, bMap.getWidth(), 0, 0, bMap.getWidth(), bMap.getHeight());  
      
          LuminanceSource source = new RGBLuminanceSource(bMap.getWidth(), bMap.getHeight(), intArray);
          BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
      
          Reader reader = new MultiFormatReader();// use this otherwise ChecksumException
          try {
              Result result = reader.decode(bitmap);
              contents = result.getText(); 
              //byte[] rawBytes = result.getRawBytes(); 
              //BarcodeFormat format = result.getBarcodeFormat(); 
              //ResultPoint[] points = result.getResultPoints();
          } catch (NotFoundException e) { e.printStackTrace(); } 
          catch (ChecksumException e) { e.printStackTrace(); }
          catch (FormatException e) { e.printStackTrace(); } 
          return contents;
      }
      

      【讨论】:

        【解决方案3】:

        Bitmap 是一个 Android 类。 Android 来自相机的默认图像格式是平面 YUV 格式。这就是为什么只需要 PlanarYUVLuminanceSource 并且对于 Android 存在。 RGBLuminanceSource 必须被移植。

        您将完全错误的数据类型放入类中。它需要 YUV 平面格式的像素。您正在传递 JPEG 文件的压缩字节。

        【讨论】:

        • 好的,谢谢你的解释。我想我现在可以通过将位图转换为 int[],然后使用 RGBLuminanceSource 构造函数
        猜你喜欢
        • 1970-01-01
        • 2013-02-23
        • 2015-01-05
        • 2012-06-09
        • 2011-06-12
        • 1970-01-01
        • 1970-01-01
        • 2010-10-31
        • 2015-08-16
        相关资源
        最近更新 更多