Created
May 18, 2018 13:42
-
-
Save AraujoJordan/571c04392b8b0e5e05da422fc605dc02 to your computer and use it in GitHub Desktop.
A SurfaceHolder implementation for QRCode Detection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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