我正在使用QRCodeReaderView https://github.com/dlazaro66/QRCodeReaderView来实现我自己的QR码扫描仪,它运行良好,但相机仍然启动缓慢(3-4秒),我想出了在使用之前预先开始预览相机的想法(当焦点在有按钮开始扫描的碎片上时保持相机打开,这样可以在需要时立即打开)我尝试了一切,但似乎我不理解这个概念,它仍然开始慢。 以下是QRCodeReaderView的代码:
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.ResultPoint;
import com.google.zxing.client.android.camera.open.CameraManager;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import java.io.IOException;
public class QRCodeReaderView extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {
public interface OnQRCodeReadListener {
public void onQRCodeRead(String text, PointF[] points);
public void cameraNotFound();
public void QRCodeNotFoundOnCamImage();
}
private OnQRCodeReadListener mOnQRCodeReadListener;
private static final String TAG = QRCodeReaderView.class.getName();
private QRCodeReader mQRCodeReader;
private int mPreviewWidth;
private int mPreviewHeight;
private SurfaceHolder mHolder;
private CameraManager mCameraManager;
public QRCodeReaderView(Context context) {
super(context);
init();
}
public QRCodeReaderView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public void setOnQRCodeReadListener(OnQRCodeReadListener onQRCodeReadListener) {
mOnQRCodeReadListener = onQRCodeReadListener;
}
public CameraManager getCameraManager() {
return mCameraManager;
}
@SuppressWarnings("deprecation")
private void init() {
if (checkCameraHardware(getContext())) {
mCameraManager = new CameraManager(getContext());
mHolder = this.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // Need to set this flag despite it's deprecated
} else {
Log.e(TAG, "Error: Camera not found");
if (mOnQRCodeReadListener != null) {
mOnQRCodeReadListener.cameraNotFound();
}
}
}
/**
* *************************************************
* SurfaceHolder.Callback,Camera.PreviewCallback
* **************************************************
*/
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
// Indicate camera, our View dimensions
mCameraManager.openDriver(holder, this.getWidth(), this.getHeight());
} catch (IOException e) {
Log.w(TAG, "Can not openDriver: " + e.getMessage());
mCameraManager.closeDriver();
}
try {
mQRCodeReader = new QRCodeReader();
mCameraManager.startPreview();
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
mCameraManager.closeDriver();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(TAG, "surfaceDestroyed");
mCameraManager.getCamera().setPreviewCallback(null);
mCameraManager.getCamera().stopPreview();
mCameraManager.getCamera().release();
mCameraManager.closeDriver();
}
// Called when camera take a frame
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
PlanarYUVLuminanceSource source = mCameraManager.buildLuminanceSource(data, mPreviewWidth, mPreviewHeight);
HybridBinarizer hybBin = new HybridBinarizer(source);
BinaryBitmap bitmap = new BinaryBitmap(hybBin);
try {
Result result = mQRCodeReader.decode(bitmap);
// Notify we found a QRCode
if (mOnQRCodeReadListener != null) {
// Transform resultPoints to View coordinates
PointF[] transformedPoints = transformToViewCoordinates(result.getResultPoints());
mOnQRCodeReadListener.onQRCodeRead(result.getText(), transformedPoints);
}
} catch (ChecksumException e) {
Log.d(TAG, "ChecksumException");
e.printStackTrace();
} catch (NotFoundException e) {
// Notify QR not found
if (mOnQRCodeReadListener != null) {
mOnQRCodeReadListener.QRCodeNotFoundOnCamImage();
}
} catch (FormatException e) {
Log.d(TAG, "FormatException");
e.printStackTrace();
} finally {
mQRCodeReader.reset();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.d(TAG, "surfaceChanged");
if (mHolder.getSurface() == null) {
Log.e(TAG, "Error: preview surface does not exist");
return;
}
//preview_width = width;
//preview_height = height;
mPreviewWidth = mCameraManager.getPreviewSize().x;
mPreviewHeight = mCameraManager.getPreviewSize().y;
mCameraManager.stopPreview();
mCameraManager.getCamera().setPreviewCallback(this);
mCameraManager.getCamera().setDisplayOrientation(90); // Portrait mode
mCameraManager.startPreview();
}
/**
* Transform result to surfaceView coordinates
* <p/>
* This method is needed because coordinates are given in landscape camera coordinates.
* Now is working but transform operations aren't very explained
* <p/>
* TODO re-write this method explaining each single value
*
* @return a new PointF array with transformed points
*/
private PointF[] transformToViewCoordinates(ResultPoint[] resultPoints) {
PointF[] transformedPoints = new PointF[resultPoints.length];
int index = 0;
if (resultPoints != null) {
float previewX = mCameraManager.getPreviewSize().x;
float previewY = mCameraManager.getPreviewSize().y;
float scaleX = this.getWidth() / previewY;
float scaleY = this.getHeight() / previewX;
for (ResultPoint point : resultPoints) {
PointF tmppoint = new PointF((previewY - point.getY()) * scaleX, point.getX() * scaleY);
transformedPoints[index] = tmppoint;
index++;
}
}
return transformedPoints;
}
/**
* Check if this device has a camera
*/
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
// this device has a camera
return true;
} else if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)) {
// this device has a front camera
return true;
} else if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) {
// this device has any camera
return true;
} else {
// no camera on this device
return false;
}
}
}
这是我使用它的片段:
package com.breadwallet.presenter.fragments;
import com.breadwallet.R;
import com.breadwallet.presenter.activities.ScanResultActivity;
import com.breadwallet.tools.animation.SpringAnimator;
import com.breadwallet.tools.qrcode.QRCodeReaderView;
public class MainFragmentDecoder extends Fragment implements QRCodeReaderView.OnQRCodeReadListener {
public static final String TAG = "MainFragmentDecoder";
private boolean accessGranted = true;
private TextView myTextView;
private static QRCodeReaderView mydecoderview;
private ImageView camera_guide_image;
private Intent intent;
public static MainFragmentDecoder mainFragmentDecoder;
private RelativeLayout layout;
public MainFragmentDecoder() {
mainFragmentDecoder = this;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_decoder, container, false);
intent = new Intent(getActivity(), ScanResultActivity.class);
myTextView = (TextView) rootView.findViewById(R.id.exampleTextView);
camera_guide_image = (ImageView) rootView.findViewById(R.id.camera_guide_image);
SpringAnimator.showExpandCameraGuide(camera_guide_image);
// Inflate the layout for this fragment
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
layout = (RelativeLayout) getView().findViewById(R.id.fragment_decoder_layout);
mydecoderview = new QRCodeReaderView(getActivity().getApplicationContext());
mydecoderview.setOnQRCodeReadListener(mainFragmentDecoder);
if (mydecoderview != null)
mydecoderview.getCameraManager().startPreview();
}
/**
* Called when a QR is decoded
* "text" : the text encoded in QR
* "points" : points where QR control points are placed
*/
@Override
public void onQRCodeRead(String text, PointF[] points) {
synchronized (this) {
if (accessGranted) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
accessGranted = true;
}
}, 300);
accessGranted = false;
// Log.e(TAG, "Activity STARTED!!!!!");
intent.putExtra("result", text);
startActivity(intent);
}
}
}
// Called when your device have no camera
@Override
public void cameraNotFound() {
Log.d(TAG, "No Camera found!");
}
// Called when there's no QR codes in the camera preview image
@Override
public void QRCodeNotFoundOnCamImage() {
// Log.d(TAG, "No QR Code found!");
}
@Override
public void onResume() {
super.onResume();
new CameraOpenerTask().execute();
}
@Override
public void onPause() {
super.onPause();
Log.e(TAG, "In onPause");
mydecoderview.getCameraManager().stopPreview();
layout.removeView(mydecoderview);
}
private class CameraOpenerTask extends AsyncTask {
@Override
protected Object doInBackground(Object[] params) {
return null;
}
@Override
protected void onPostExecute(Object o) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
layout.addView(mydecoderview, 0);
}
}, 1300);
Log.e(TAG, "The camera started");
}
}
public void stopCamera() {
if (mydecoderview != null) {
mydecoderview.getCameraManager().stopPreview();
}
mydecoderview = null;
}
}
我试过了:
答案 0 :(得分:-1)
例如一个例子......:你可以在 CyanogenMod (11版)固件中尝试照片应用 ...也许这只是你的意思寻找? 从它的源代码下载并将其添加到您的代码中...... 所有这些我说因为这个应用程序工作快速而正确...所以..你可以使用它!