/** * Decode the data within the viewfinder rectangle, and time how long it took. For efficiency, * reuse the same reader objects from one decode to the next. * * @param data The YUV preview frame. * @param width The width of the preview frame. * @param height The height of the preview frame. */ privatevoiddecode(byte[] data, int width, int height){ long start = System.currentTimeMillis(); Result rawResult = null; Handler handler = mIScanCallback.getScanHandler(); try { if (null == mRotatedData) { mRotatedData = newbyte[width * height]; } else { if (mRotatedData.length < width * height) { mRotatedData = newbyte[width * height]; } } Arrays.fill(mRotatedData, (byte) 0); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (x + y * width >= data.length) { break; } mRotatedData[x * height + height - y - 1] = data[x + y * width]; } } int tmp = width; // Here we are swapping, that's the difference to #11 width = height; height = tmp; }
/** * Decode the data within the viewfinder rectangle, and time how long it took. For efficiency, * reuse the same reader objects from one decode to the next. * * @param data The YUV preview frame. * @param width The width of the preview frame. * @param height The height of the preview frame. */ privatevoiddecode(byte[] data, int width, int height){ long start = System.currentTimeMillis(); Result rawResult = null; Handler handler = mIScanCallback.getScanHandler(); try { PlanarYUVLuminanceSource source = mIScanCallback.buildLuminanceSource(data, width, height); if (source != null) { BinaryBitmap bitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source));// try { rawResult = multiFormatReader.decodeWithState(bitmap); } catch (ReaderException re) { // continue } finally { multiFormatReader.reset(); } } 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, DECODE_SUCCEEDED, rawResult); //为了提高扫码速度,去除这里的生成bitmap的操作 // Bundle bundle = new Bundle(); // bundleThumbnail(source, bundle); // message.setData(bundle); message.sendToTarget(); } } else { if (handler != null) { Message message = Message.obtain(handler, DECODE_FAILED); message.sendToTarget(); } } } catch (ArrayIndexOutOfBoundsException e) { if (handler != null) { Message message = Message.obtain(handler, DECODE_FAILED); message.sendToTarget(); } } }
/** * Like {@link #getFramingRect} but coordinates are in terms of the preview frame, * not UI / screen. * * @return {@link Rect} expressing barcode scan area in terms of the preview size */ publicsynchronized Rect getFramingRectInPreview() { if (framingRectInPreview == null) { Rect framingRect = getFramingRect(); if (framingRect == null) { returnnull; } Rect rect = new Rect(framingRect); Point cameraResolution = configManager.getCameraResolution(); Point screenResolution = configManager.getScreenResolution(); if (cameraResolution == null || screenResolution == null) { // Called early, before init even finished returnnull; } int left, top, right, bottom; //坐标转换, 我们二维码扫描是竖屏,图像是横屏,所以需要计算二维码所处的相对坐标 left = rect.top * cameraResolution.x / screenResolution.y; top = rect.left * cameraResolution.y / screenResolution.x; right = left + rect.height() * cameraResolution.x / screenResolution.y; bottom = top + rect.width() * cameraResolution.y / screenResolution.x; //对应一些相机在竖屏下需要旋转270 才能够正常图像,但是图像是横屏的,这个图像也是调转的,所以也需要转换 if (getCWNeededRotation() == 270) { intwidth = right - left; left = cameraResolution.x - left - width; right = left + width; } rect.left = left; rect.top = top; rect.right = right; rect.bottom = bottom; framingRectInPreview = rect; } return framingRectInPreview; }
privatebyte[] mOriginData; privatebyte[] mRotatedData; /** * A factory method to build the appropriate LuminanceSource object based on the format * of the preview buffers, as described by Camera.Parameters. * * @param data A preview frame. * @param width The width of the image. * @param height The height of the image. * @return A PlanarYUVLuminanceSource instance. */ public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height){ Rect rect = getFramingRectInPreview(); if (rect == null) { return null; } int previewH = rect.height(); int previewW = rect.width(); int size = previewH * previewW; if (null == mOriginData) { mOriginData = newbyte[size]; mRotatedData = newbyte[size]; } else { if (mOriginData.length < size) { mOriginData = newbyte[size]; mRotatedData = newbyte[size]; } } int inputOffset = rect.top * width + rect.left; // If the width matches the full width of the underlying data, perform a single copy. if (width == previewW) { System.arraycopy(data, inputOffset, mOriginData, 0, size); } // Otherwise copy one cropped row at a time. for (int y = 0; y < previewH; y++) { int outputOffset = y * previewW; System.arraycopy(data, inputOffset, mOriginData, outputOffset, previewW); inputOffset += width; } for (int y = 0; y < previewH; y++) { for (int x = 0; x < previewW; x++) { if (x + y * previewW >= mOriginData.length) { break; } mRotatedData[x * previewH + previewH - y - 1] = mOriginData[x + y * previewW]; } } int tmp = previewW; // Here we are swapping, that's the difference to #11 previewW = previewH; previewH = tmp; // Go ahead and assume it's YUV rather than die. returnnewPlanarYUVLuminanceSource(mRotatedData, previewW, previewH, 0, 0, previewW, previewH, false); }