【问题标题】:Taking a photo upon QR code scan扫描二维码拍照
【发布时间】:2013-08-03 12:51:42
【问题描述】:

我有一个集成了 zxing 的应用程序。我一直在考虑在扫描 QR 码时尝试存储照片。肖恩·欧文(Sean Owen)推荐了以下内容:

“应用程序正在从相机获取连续的帧流进行分析。您可以通过在预览回调中截取它们来存储其中的任何一个。”

据我所知,预览回调的唯一实例是在 CameraManager.java 活动 (https://code.google.com/p/zxing/source/browse/trunk/android/src/com/google/zxing/client/android/camera/CameraManager.java) 中。

特别是:

public synchronized void requestPreviewFrame(Handler handler, int message) {
Camera theCamera = camera;
if (theCamera != null && previewing) {
  previewCallback.setHandler(handler, message);
  theCamera.setOneShotPreviewCallback(previewCallback);
}}

由于它运行每一帧,我没有保存(最好是字节日期)任何特定帧的方法。我本以为会有一些东西被传递回 CaptureActivity.java 类(链接在底部),但是我自己没有找到任何东西。

任何使用过 Zxing 的人都知道,扫描后会在扫描数据的屏幕上显示幽灵图像,如果有可能劫持这部分代码并将该数据转换和/或保存为字节码,可能也很有用。

任何帮助或其他想法将不胜感激。对任何进一步信息的请求将得到迅速回应。谢谢。

此文件夹中的完整代码:https://code.google.com/p/zxing/source/browse/trunk#trunk%2Fandroid%2Fsrc%2Fcom%2Fgoogle%2Fzxing%2Fclient%2Fandroid

更新:

到目前为止,以下代码部分似乎是保存字节数据的可能位置,它们都在 DecodeHandler.java 类中。

private void decode(byte[] data, int width, int height) {
long start = System.currentTimeMillis();
Result rawResult = null;
PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);
if (source != null) {
  BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

  //here?

  try {
    rawResult = multiFormatReader.decodeWithState(bitmap);
  } catch (ReaderException re) {
    // continue
  } finally {
    multiFormatReader.reset();
  }
}

Handler handler = activity.getHandler();
if (rawResult != null) {
  // Don't log the barcode contents for security.
  long end = System.currentTimeMillis();
  Log.d(TAG, "Found barcode in " + (end - start) + " ms");
  if (handler != null) {
    Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult);
    Bundle bundle = new Bundle();
    Bitmap grayscaleBitmap = toBitmap(source, source.renderCroppedGreyscaleBitmap());

    //I believe this bitmap is the one shown on screen after a scan has been performed

    bundle.putParcelable(DecodeThread.BARCODE_BITMAP, grayscaleBitmap);
    message.setData(bundle);
    message.sendToTarget();
  }
} else {
  if (handler != null) {
    Message message = Message.obtain(handler, R.id.decode_failed);
    message.sendToTarget();
  }
}}


  private static Bitmap toBitmap(LuminanceSource source, int[] pixels) {
int width = source.getWidth();
int height = source.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);

//saving the bitmnap at this point or slightly sooner, before grey scaling could work.

return bitmap;}

更新:在 PreviewCallback.java 中找到请求的代码

public void onPreviewFrame(byte[] data, Camera camera) {
Point cameraResolution = configManager.getCameraResolution();
Handler thePreviewHandler = previewHandler;
if (cameraResolution != null && thePreviewHandler != null) {
  Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,
      cameraResolution.y, data);
  message.sendToTarget();
  previewHandler = null;
} else {
  Log.d(TAG, "Got preview callback, but no handler or resolution available");
}

【问题讨论】:

    标签: java android photo zxing scanning


    【解决方案1】:

    预览回调的数据为 NV21 格式。所以如果你想保存它,你可以使用这样的代码:

    YuvImage im = new YuvImage(byteArray, ImageFormat.NV21, width,
                            height, null);
                Rect r = new Rect(0, 0, width, height);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                im.compressToJpeg(r, 50, baos);
    
                try {
                      FileOutputStream output = new FileOutputStream("/sdcard/test_jpg.jpg");
                      output.write(baos.toByteArray());
                      output.flush();
                      output.close();
                } catch (FileNotFoundException e) {
                } catch (IOException e) {
                }
    

    保存点是ZXing可以解码byte[]并成功返回内容字符串。

    【讨论】:

    • 我认为我应该在这种方法中保存数据是否正确:public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) { Rect rect = getFramingRectInPreview(); if (rect == null) { return null; } // Go ahead and assume it's YUV rather than die. return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top, rect.width(), rect.height(), false); }
    • byte[] 数据来自预览回调,跟随它找到合适的点保存。您也可以搜索关键字“解码”
    • 我已经用一些可能的保存点更新了原始帖子,但是它们似乎不属于通过您的方法保存的必要标准。感谢您的想法和反馈。
    • 你能找到onPreviewFrame(byte[] data, Camera camera),在其中你从camera preview获取数据吗?
    • 我提出了一个新问题以进一步详细说明这一问题,我们将不胜感激。谢谢你。 stackoverflow.com/questions/18149620/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多