0

In my android coding I have a camera surface view class, when I show the preview for this camera class it's a live camera scene, but how can I create a function that create a bitmap for the camera current frame? So I can get the captured bitmap from other class.

Any guidance will be appreciated~

This is my camera class coding:

import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;

public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {

Camera mCamera;
boolean isPreviewRunning = false;

CameraSurfaceView(Context context) {
    super(context);
    SurfaceHolder mHolder = getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void surfaceCreated(SurfaceHolder holder) {
    synchronized(this) {
        mCamera = Camera.open();
        try {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException e) {
            Log.e("Camera", "mCamera.setPreviewDisplay(holder);");
        }
        mCamera.setDisplayOrientation(90);
        mCamera.startPreview();

    }
}

public void surfaceDestroyed(SurfaceHolder holder) {
    synchronized(this) {
        try {
            if (mCamera!=null) {
                mCamera.stopPreview();
                isPreviewRunning=false;
                mCamera.release();
            }
        } catch (Exception e) {
            Log.e("Camera", e.getMessage());
        }
    }
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

}

}
Le Parkour
  • 97
  • 1
  • 15

1 Answers1

1

Note that below codes are for capturing image with its displayed pixels, not for taking camera. It means, the result image will give actual pixel size of the screen (ie, 1080x768), not multi-megapixel high resolution image of the Camera app. If you want to take an image as Camera app provided, use takePicture method.

In order to capture live preview image in SurfaceView,

public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
    private static final String TAG = "CameraSurfaceView";

    private SurfaceHolder mSurfaceHolder;
    private Camera mCamera = null;
    private Bitmap mBitmap;
    private Context mContext;
    private Camera.Parameters mParameters;
    private byte[] byteArray;
    private List<Camera.Size> mSupportedPreviewSizes;
    private Camera.Size mPreviewSize;

    public CameraSurfaceView (Context context) {
        this(context, null);
    }

    public CameraSurfaceView (Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CameraSurfaceView (Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;

        try {
            mSurfaceHolder = getHolder();
            mSurfaceHolder.addCallback(this);
            mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceCreated(final SurfaceHolder surfaceHolder) {
        if (mCamera == null) {
            try {
                mCamera = Camera.open();
            } catch (RuntimeException ignored) {
            }
        }

        try {
            if (mCamera != null) {
                WindowManager winManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
                mCamera.setPreviewDisplay(mSurfaceHolder);
            }
        } catch (Exception e) {
            if (mCamera != null)
                mCamera.release();
            mCamera = null;
        }

        if (mCamera == null) {
                return;
        } else {
            mCamera.setPreviewCallback(new Camera.PreviewCallback() {
                @Override
                public void onPreviewFrame(byte[] bytes, Camera camera) {
                    if (mParameters == null)
                    {
                        return;
                    }
                    byteArray = bytes;
                }
            });
        }

        setWillNotDraw(false);
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
        try {
            mParameters = mCamera.getParameters();

            List<Size> cameraSize = mParameters.getSupportedPreviewSizes();
            mPreviewSize = cameraSize.get(0);

            for (Size s : cameraSize) {
                if ((s.width * s.height) > (mPreviewSize.width * mPreviewSize.height)) {
                    mPreviewSize = s;
                }
            }

            mParameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
            mCamera.setParameters(mParameters);
            mCamera.startPreview();

        } catch (Exception e) {
            if (mCamera != null) {
                mCamera.release();
                mCamera = null;
            }
        }
    }


    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        if (mCamera != null) {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    public Bitmap getBitmap() {
        try {
            if (mParameters == null)
                return null;

            if (mPreviewSize == null)
                return null;

            int format = mParameters.getPreviewFormat();
            YuvImage yuvImage = new YuvImage(byteArray, format, mPreviewSize.width, mPreviewSize.height, null);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

            Rect rect = new Rect(0, 0, mPreviewSize.width, mPreviewSize.height);

            yuvImage.compressToJpeg(rect, 75, byteArrayOutputStream);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPurgeable = true;
            options.inInputShareable = true;
            mBitmap = BitmapFactory.decodeByteArray(byteArrayOutputStream.toByteArray(), 0, byteArrayOutputStream.size(), options);

            byteArrayOutputStream.flush();
            byteArrayOutputStream.close();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }

        return mBitmap;
    }

    public Camera getCamera() {
        return mCamera;
    }
}
Youngjae
  • 24,352
  • 18
  • 113
  • 198