Camera的onPreviewFrame回调方法中图片帧数据data最后显示出现错位拼接的bug

来源:互联网 发布:win7 tcp监听端口阻塞 编辑:程序博客网 时间:2024/06/11 11:05

修复后的代码:

1)初始化Camera

boolean initCamera(SurfaceHolder holder) {if (mCamera == null) {prepareScanner();}if (mCamera == null) {// prepare failed!return false;}assert holder != null;if (executor == null) {createExecutor();checker = initDoubleChecker();}if (mPreviewBuffer == null) {int previewFormat = ImageFormat.NV21; // the default.Camera.Parameters parameters = mCamera.getParameters();previewFormat = parameters.getPreviewFormat();int bytesPerPixel = ImageFormat.getBitsPerPixel(previewFormat) / 8;int bufferSize = mPreviewWidth * mPreviewHeight * bytesPerPixel * 3;mPreviewBuffer = new byte[recognizerNumber][bufferSize];<span style="color:#ff0000;">for(int i=0; i<recognizerNumber; i++) {mCamera.addCallbackBuffer(mPreviewBuffer[i]);<span style="white-space:pre"></span>//此处添加多个buffer用于缓存onPreviewFrame中的data}</span>}holder.addCallback(this);holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
<pre name="code" class="java"><span style="color:#ff0000;"><span style="white-space:pre"></span>//这里必须为mCamera设置预览回调缓存监听。如果data到来时有可用buffer,则data被加入buffer。其中Camera是全局变量,与onPreviewFrame中回调返回的camer是一致的</span>
mCamera.setPreviewCallbackWithBuffer(this);if (isSurfaceValid) {makePreviewGo(holder);}captureStart = System.currentTimeMillis();// nResetAnalytics();return true;}

2)处理摄像头返回的图片帧数据
@Overridepublic void onPreviewFrame(final byte[] data, final Camera camera) {if (data == null) {return;}//saveBitmap(data, count+"s", mPreviewWidth, mPreviewHeight);//count++;if (shallStartAutoFocus()) {triggerAutoFocus();}// TODO: eliminate this foolishness and measure/layout properly.if (mFirstPreviewFrame) {mFirstPreviewFrame = false;mFirstPreviewFrameAt = System.currentTimeMillis();mFrameOrientation = mScanActivityRef.get().getFrameOrientation();}final CardRecognizer recognizer = getRecognizer();if (executor != null && !executor.isShutdown() && recognizer != null) {executor.execute(new Runnable() {@Overridepublic void run() {if (executor != null && !executor.isShutdown()) {final ExecutorService thisExecutor = executor;int rotateDegree = (90 * mFrameOrientation) % 360;Rect guideRect = getGuideFrame();Rect cropRect = new Rect();int padding = 0;padding = Math.min(guideRect.left, guideRect.top);cropRect.left = guideRect.left - padding;cropRect.right = guideRect.right + padding;cropRect.top = guideRect.top - padding;cropRect.bottom = guideRect.bottom + padding;TimingLogger timingLogger = new TimingLogger(Util.TIMING_LOG_TAG, "onPreviewFrame new thread");Bitmap cropedBitmap = null;synchronized (thisExecutor) {timingLogger.addSplit("synchronized waiting for NV21ToRGBABitmap");if (!thisExecutor.isShutdown()) {saveBitmap(data, count1+"t", mPreviewWidth, mPreviewHeight);count1++;cropedBitmap = Util.NV21ToRGBABitmap(data, mPreviewWidth, mPreviewHeight, rotateDegree,cropRect, mScanActivityRef.get().getApplicationContext());if(cameraInfoOrientation == 270){cropedBitmap = Util.rotateBitmapByDegree(cropedBitmap, 180);}}}final CardDoubleChecker thisChecker = checker;timingLogger.addSplit("NV21ToRGBABitmap");STService service = STService.getInstance(null);boolean activated = service.isActivated();if (cropedBitmap != null && !thisExecutor.isShutdown()) {Card card = onRecognize(recognizer, guideRect, cropRect, cropedBitmap);timingLogger.addSplit("recognizeCard");if (card != null && thisChecker != null) {synchronized (thisChecker) {if (!thisExecutor.isShutdown()) {boolean doubleCheck = thisChecker.doubleCheck(card);timingLogger.addSplit("doubleCheck");if (doubleCheck && !thisExecutor.isShutdown()) {thisExecutor.shutdown();if (mScanActivityRef.get() instanceof IDCardActivity) {activated = activated || service.verifyConnect();if (activated){mScanActivityRef.get().onCardDetected(card, cropedBitmap,recognizer.getImgCardDetected(),((IDCardRecognizer) recognizer).getImgCardFace());service.recognizeIdcard(cropedBitmap);}if(!activated) activated = service.recognizeIdcard(cropedBitmap);if(!activated) mScanActivityRef.get().setResultAndFinish(CardActivity.RESULT_RECOGNIZER_INIT_FAILED, null);} else if (mScanActivityRef.get() instanceof BankCardActivity) {activated = activated || service.verifyConnect();if (activated){mScanActivityRef.get().onCardDetected(card, cropedBitmap,recognizer.getImgCardDetected());service.recognizeBankcard(cropedBitmap);}if(!activated) activated = service.recognizeBankcard(cropedBitmap);if(!activated) mScanActivityRef.get().setResultAndFinish(CardActivity.RESULT_RECOGNIZER_INIT_FAILED, null);}}}}}}//else if (!service.recognizeBankcard(cropedBitmap)) {//mScanActivityRef.get().setResultAndFinish(CardActivity.RESULT_RECOGNIZER_INIT_FAILED, null);//}timingLogger.dumpToLog();}// give the image buffer back to the camera, AFTER we're done reading// the image.<span style="color:#ff0000;">if (camera != null) {<span style="white-space:pre"></span>//给camera预设下一帧(或未来帧)的缓存buffer。必须放在图像处理完后的最后位置camera.addCallbackBuffer(data);}</span>releaseRecognizer(recognizer);}});}}


0 0