Skip to content

Instantly share code, notes, and snippets.

@AraujoJordan
Created May 18, 2018 13:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AraujoJordan/571c04392b8b0e5e05da422fc605dc02 to your computer and use it in GitHub Desktop.
Save AraujoJordan/571c04392b8b0e5e05da422fc605dc02 to your computer and use it in GitHub Desktop.
A SurfaceHolder implementation for QRCode Detection
package cultura.ministerio.culturi.utils;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.util.Log;
import android.util.SparseArray;
import android.view.SurfaceHolder;
import com.google.android.gms.vision.Frame;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by Jordan on 04/04/2016.
*/
public class TorchSurface implements SurfaceHolder.Callback, Camera.PreviewCallback {
private Camera mCamera;
private BarcodeDetector detector;
protected Activity act;
private Timer timer;
private QrCodeListener listener;
public TorchSurface(Activity act, QrCodeListener listener) {
detector = new BarcodeDetector.Builder(act)
.setBarcodeFormats(Barcode.QR_CODE)
.build();
this.listener = listener;
this.act = act;
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
public void runBarcodeFinder() {
Log.v(getClass().getSimpleName(), "load Finder");
timer = new Timer();
int interval = 3000;
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
act.runOnUiThread(new Runnable() {
@Override
public void run() {
if (detector.isOperational()) {
Log.v(TorchSurface.class.getSimpleName(), "Searching for barcodes");
mCamera.setOneShotPreviewCallback(TorchSurface.this);
}
}
});
}
}, interval, interval);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
mCamera.startPreview();
mCamera.setDisplayOrientation(90);
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
try {
Camera.Parameters parameters = camera.getParameters();
int format = parameters.getPreviewFormat();
//YUV formats require more conversion
if (format == ImageFormat.NV21 || format == ImageFormat.YUY2 || format == ImageFormat.NV16) {
int w = parameters.getPreviewSize().width;
int h = parameters.getPreviewSize().height;
// Get the YuV image
YuvImage yuv_image = new YuvImage(data, format, w, h, null);
// Convert YuV to Jpeg
Rect rect = new Rect(0, 0, w, h);
ByteArrayOutputStream output_stream = new ByteArrayOutputStream();
yuv_image.compressToJpeg(rect, 100, output_stream);
byte[] byt = output_stream.toByteArray();
Bitmap bitmap = BitmapFactory.decodeByteArray(byt, 0, byt.length);
Matrix matrix = new Matrix();
matrix.postRotate(90);
bitmap = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(),
matrix, true);
Frame frame = new Frame.Builder().setBitmap(bitmap).build();
SparseArray<Barcode> barcodes = detector.detect(frame);
if (barcodes != null && barcodes.size() > 0) {
Log.v(TorchSurface.class.getSimpleName(), "Found barcode");
listener.qrCodeFound(barcodes.valueAt(0).rawValue);
timer.cancel();
} else
Log.v(TorchSurface.class.getSimpleName(), "Not Found: " + barcodes.size());
} else
Log.v(TorchSurface.class.getSimpleName(), "Detector is not operational yet");
} catch (Exception error) {
error.printStackTrace();
}
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
}
});
}
public interface QrCodeListener {
void qrCodeFound(String tokenFound);
}
public void onPause() {
if(timer!=null)
timer.cancel();
}
public void onResume() {
runBarcodeFinder();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment