Skip to content

Commit

Permalink
Fixes camera preview
Browse files Browse the repository at this point in the history
  • Loading branch information
YOOJIA.CHEN committed Sep 27, 2016
1 parent d9c9f88 commit 0e91e93
Show file tree
Hide file tree
Showing 10 changed files with 363 additions and 116 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package com.github.yoojia.zxing.app;

import android.graphics.Bitmap;
import android.hardware.Camera;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;

import com.github.yoojia.qrcode.camera.Cameras;
import com.github.yoojia.qrcode.camera.CaptureCallback;
import com.github.yoojia.qrcode.camera.CameraPreviewView;
import com.github.yoojia.qrcode.camera.LiveCameraView;
import com.github.yoojia.zxing.R;

Expand All @@ -16,24 +20,40 @@
*/
public class QRCodeScanActivity extends AppCompatActivity {

private LiveCameraView mCameraView;
public static final String TAG = QRCodeScanActivity.class.getSimpleName();

private Camera mCamera;
private LiveCameraView mLiveCameraView;

private ImageView mCaptureImage;

private final CaptureCallback mCaptureCallback = new CaptureCallback() {
@Override public void onCaptured(Bitmap bitmap) {
Log.i(TAG, "-> Got bitmap, show to capture view");
mCaptureImage.setImageBitmap(bitmap);
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_scan);
mCameraView = (LiveCameraView) findViewById(R.id.capture_preview_view);
mCamera = Cameras.open(0);
mCameraView.setCamera(mCamera);
}
mCaptureImage = (ImageView) findViewById(R.id.capture_image);
mLiveCameraView = (LiveCameraView) findViewById(R.id.capture_preview_view);
mLiveCameraView.setPreviewReadyCallback(new CameraPreviewView.PreviewReadyCallback() {
@Override
public void onStarted(Camera camera) {
Log.i(TAG, "-> Camera started, start to auto capture");
mLiveCameraView.startAutoCapture(2500, mCaptureCallback);
}

@Override
protected void onDestroy() {
super.onDestroy();
mCamera.release();
@Override
public void onStopped() {
Log.i(TAG, "-> Camera stopped");
mLiveCameraView.stopAutoCapture();
}
});
}

}
27 changes: 0 additions & 27 deletions app/src/main/res/layout/activity_camera.xml

This file was deleted.

10 changes: 10 additions & 0 deletions app/src/main/res/layout/activity_scan.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,14 @@
android:layout_height="match_parent"
android:layout_gravity="center" />

<ImageView
android:id="@+id/capture_image"
android:layout_width="120dp"
android:layout_height="80dp"/>

<!--
<com.github.yoojia.qrcode.camera.LiveFocusView
android:layout_width="match_parent"
android:layout_height="match_parent"
/>-->
</RelativeLayout>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package com.github.yoojia.qrcode.camera;

import android.content.Context;
import android.hardware.Camera;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.IOException;

/**
* @author Yoojia Chen (yoojiachen@gmail.com)
* @since 2.0
*/
public class CameraPreviewView extends SurfaceView implements SurfaceHolder.Callback {

private final static String TAG = CameraPreviewView.class.getSimpleName();

private Camera mCamera;
private SurfaceHolder mSurfaceHolder;
private PreviewReadyCallback mPreviewReadyCallback;

public CameraPreviewView(Context context) {
super(context);
init();
}

public CameraPreviewView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public CameraPreviewView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

private void init(){
mSurfaceHolder = this.getHolder();
mSurfaceHolder.addCallback(this);
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "Start preview display[SURFACE-CREATED]");
startPreviewDisplay(holder);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mSurfaceHolder.getSurface() == null){
return;
}
Cameras.followScreenOrientation(getContext(), mCamera);
Log.d(TAG, "Restart preview display[SURFACE-CHANGED]");
stopPreviewDisplay();
startPreviewDisplay(mSurfaceHolder);
}

public void setCamera(Camera camera) {
mCamera = camera;
final Camera.Parameters params = mCamera.getParameters();
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
params.setSceneMode(Camera.Parameters.SCENE_MODE_BARCODE);
}

public void setPreviewReadyCallback(PreviewReadyCallback previewCallback) {
mPreviewReadyCallback = previewCallback;
}

private void startPreviewDisplay(SurfaceHolder holder){
checkCamera();
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.e(TAG, "Error while START preview for camera", e);
}
if (mPreviewReadyCallback != null) {
mPreviewReadyCallback.onStarted(mCamera);
}
}

private void stopPreviewDisplay(){
checkCamera();
try {
mCamera.stopPreview();
} catch (Exception e){
Log.e(TAG, "Error while STOP preview for camera", e);
}
if (mPreviewReadyCallback != null) {
mPreviewReadyCallback.onStopped();
}
}

private void checkCamera(){
if(mCamera == null) {
throw new IllegalStateException("Camera must be set when start/stop preview, call <setCamera(Camera)> to set");
}
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(TAG, "Stop preview display[SURFACE-DESTROYED]");
stopPreviewDisplay();
}

public interface PreviewReadyCallback {

void onStarted(Camera camera);

void onStopped();
}
}
26 changes: 24 additions & 2 deletions qrcode/src/main/java/com/github/yoojia/qrcode/camera/Cameras.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;

import java.io.ByteArrayOutputStream;

/**
* @author Yoojia Chen (yoojiachen@gmail.com)
* @since 2.0
Expand Down Expand Up @@ -56,7 +63,22 @@ public static void followScreenOrientation(Context context, Camera camera){
}
}

public static void tackJPEGPicture(Camera camera, BitmapCallback callback) {
camera.takePicture(null, null, callback);
public static Bitmap previewCapture(Camera camera, byte[] data){
final Camera.Parameters parameters = camera.getParameters();
final int width = parameters.getPreviewSize().width;
final int height = parameters.getPreviewSize().height;
final YuvImage yuv = new YuvImage(data, parameters.getPreviewFormat(), width, height, null);
final ByteArrayOutputStream out = new ByteArrayOutputStream();
yuv.compressToJpeg(new Rect(0, 0, width, height), 100, out);// Best
final byte[] bytes = out.toByteArray();
final Bitmap src = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
final Matrix matrix = new Matrix();
matrix.setRotate(90);
final int originWidth = src.getWidth();
final int originHeight = src.getHeight();
final int targetWH = originWidth > originHeight ? originHeight : originWidth;
final int offsetX = originWidth > originHeight ? (originWidth - originHeight): 0;
final int offsetY = originWidth > originHeight ? 0 : (originHeight - originWidth);
return Bitmap.createBitmap(src, offsetX, offsetY, targetWH, targetWH, matrix, true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.github.yoojia.qrcode.camera;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;

/**
* @author Yoojia Chen (yoojiachen@gmail.com)
* @since 2.0
*/
public interface CaptureCallback {

void onCaptured(Bitmap bitmap);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.github.yoojia.qrcode.camera;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

/**
* @author Yoojia Chen (yoojiachen@gmail.com)
* @since 2.0
*/
public abstract class DelayedFocusLooper {

public static final String TAG = DelayedFocusLooper.class.getSimpleName();

private static final int MSG_FOCUS = 999;

private boolean mAllowNextFocus = false;

private final Handler mDelayedHandler = new Handler(new Handler.Callback() {
@Override public boolean handleMessage(Message msg) {
Log.i(TAG, "-> Call auto focus");
callAutoFocus();
if (mAllowNextFocus) {
sendNextAutoFocus(mPeriod);
}
return true;
}
});

private int mPeriod = 1000;

public void start(int period) {
mAllowNextFocus = true;
mPeriod = period;
Log.i(TAG, "-> Start auto focus with period: " + period);
sendNextAutoFocus(period);
}

public void stop(){
Log.i(TAG, "-> Stop auto focus");
mAllowNextFocus = false;
mDelayedHandler.removeMessages(MSG_FOCUS);
}

private void sendNextAutoFocus(int period){
mDelayedHandler.sendEmptyMessageDelayed(MSG_FOCUS, period);
}

public abstract void callAutoFocus();
}
Loading

0 comments on commit 0e91e93

Please sign in to comment.