package org.opencv.android;import java.util.List;import android.content.Context;import android.graphics.ImageFormat;import android.graphics.SurfaceTexture;import android.hardware.Camera;import android.hardware.Camera.PreviewCallback;import android.os.Build;import android.util.AttributeSet;import android.util.Log;import android.view.ViewGroup.LayoutParams;import org.opencv.core.CvType;import org.opencv.core.Mat;import org.opencv.core.Size;import org.opencv.imgproc.Imgproc;/** * This class is an implementation of the Bridge View between OpenCV and Java Camera. * This class relays on the functionality available in base class and only implements * required functions: * connectCamera - opens Java camera and sets the PreviewCallback to be delivered. * disconnectCamera - closes the camera and stops preview. * When frame is delivered via callback from Camera - it processed via OpenCV to be * converted to RGBA32 and then passed to the external callback for modifications if required. */public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallback {    private static final int MAGIC_TEXTURE_ID = 10;    private static final String TAG = "JavaCameraView";    private byte mBuffer[];    private Mat[] mFrameChain;    private int mChainIdx = 0;    private Thread mThread;    private boolean mStopThread;    protected Camera mCamera;    protected JavaCameraFrame[] mCameraFrame;    private SurfaceTexture mSurfaceTexture;    public static class JavaCameraSizeAccessor implements ListItemAccessor {        @Override        public int getWidth(Object obj) {            Camera.Size size = (Camera.Size) obj;            return size.width;        }        @Override        public int getHeight(Object obj) {            Camera.Size size = (Camera.Size) obj;            return size.height;        }    }    public JavaCameraView(Context context, int cameraId) {        super(context, cameraId);    }    public JavaCameraView(Context context, AttributeSet attrs) {        super(context, attrs);    }    protected boolean initializeCamera(int width, int height) {        Log.d(TAG, "Initialize java camera");        boolean result = true;        synchronized (this) {            mCamera = null;            if (mCameraIndex == CAMERA_ID_ANY) {                Log.d(TAG, "Trying to open camera with old open()");                try {                    mCamera = Camera.open();                }                catch (Exception e){                    Log.e(TAG, "Camera is not available (in use or does not exist): " + e.getLocalizedMessage());                }                if(mCamera == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {                    boolean connected = false;                    for (int camIdx = 0; camIdx < Camera.getNumberOfCameras(); ++camIdx) {                        Log.d(TAG, "Trying to open camera with new open(" + Integer.valueOf(camIdx) + ")");                        try {                            mCamera = Camera.open(camIdx);                            connected = true;                        } catch (RuntimeException e) {                            Log.e(TAG, "Camera #" + camIdx + "failed to open: " + e.getLocalizedMessage());                        }                        if (connected) break;                    }                }            } else {                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {                    int localCameraIndex = mCameraIndex;                    if (mCameraIndex == CAMERA_ID_BACK) {                        Log.i(TAG, "Trying to open back camera");                        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();                        for (int camIdx = 0; camIdx < Camera.getNumberOfCameras(); ++camIdx) {                            Camera.getCameraInfo( camIdx, cameraInfo );                            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {                                localCameraIndex = camIdx;                                break;                            }                        }                    } else if (mCameraIndex == CAMERA_ID_FRONT) {                        Log.i(TAG, "Trying to open front camera");                        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();                        for (int camIdx = 0; camIdx < Camera.getNumberOfCameras(); ++camIdx) {                            Camera.getCameraInfo( camIdx, cameraInfo );                            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {                                localCameraIndex = camIdx;                                break;                            }                        }                    }                    if (localCameraIndex == CAMERA_ID_BACK)                    {                        Log.e(TAG, "Back camera not found!");                    }                    else if (localCameraIndex == CAMERA_ID_FRONT)                    {                        Log.e(TAG, "Front camera not found!");                    } else {                        Log.d(TAG, "Trying to open camera with new open(" + Integer.valueOf(localCameraIndex) + ")");                        try {                            mCamera = Camera.open(localCameraIndex);                        } catch (RuntimeException e) {                            Log.e(TAG, "Camera #" + localCameraIndex + "failed to open: " + e.getLocalizedMessage());                        }                    }                }            }            if (mCamera == null)                return false;            /* Now set camera parameters */            try {                Camera.Parameters params = mCamera.getParameters();                Log.d(TAG, "getSupportedPreviewSizes()");                List<android.hardware.Camera.Size> sizes = params.getSupportedPreviewSizes();                if (sizes != null) {                    /* Select the size that fits surface considering maximum size allowed */                    Size frameSize = calculateCameraFrameSize(sizes, new JavaCameraSizeAccessor(), width, height);                    params.setPreviewFormat(ImageFormat.NV21);                    Log.d(TAG, "Set preview size to " + Integer.valueOf((int)frameSize.width) + "x" + Integer.valueOf((int)frameSize.height));                    params.setPreviewSize((int)frameSize.width, (int)frameSize.height);                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && !android.os.Build.MODEL.equals("GT-I9100"))                        params.setRecordingHint(true);                    List<String> FocusModes = params.getSupportedFocusModes();                    if (FocusModes != null && FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))                    {                        params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);                    }                    mCamera.setParameters(params);                    params = mCamera.getParameters();                    mFrameWidth = params.getPreviewSize().width;                    mFrameHeight = params.getPreviewSize().height;                    if ((getLayoutParams().width == LayoutParams.MATCH_PARENT) && (getLayoutParams().height == LayoutParams.MATCH_PARENT))                        mScale = Math.min(((float)height)/mFrameHeight, ((float)width)/mFrameWidth);                    else                        mScale = 0;                    if (mFpsMeter != null) {                        mFpsMeter.setResolution(mFrameWidth, mFrameHeight);                    }                    int size = mFrameWidth * mFrameHeight;                    size  = size * ImageFormat.getBitsPerPixel(params.getPreviewFormat()) / 8;                    mBuffer = new byte[size];                    mCamera.addCallbackBuffer(mBuffer);                    mCamera.setPreviewCallbackWithBuffer(this);                    mFrameChain = new Mat[2];                    mFrameChain[0] = new Mat(mFrameHeight + (mFrameHeight/2), mFrameWidth, CvType.CV_8UC1);                    mFrameChain[1] = new Mat(mFrameHeight + (mFrameHeight/2), mFrameWidth, CvType.CV_8UC1);                    AllocateCache();                    mCameraFrame = new JavaCameraFrame[2];                    mCameraFrame[0] = new JavaCameraFrame(mFrameChain[0], mFrameWidth, mFrameHeight);                    mCameraFrame[1] = new JavaCameraFrame(mFrameChain[1], mFrameWidth, mFrameHeight);                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {                        mSurfaceTexture = new SurfaceTexture(MAGIC_TEXTURE_ID);                        mCamera.setPreviewTexture(mSurfaceTexture);                    } else                       mCamera.setPreviewDisplay(null);                    /* Finally we are ready to start the preview */                    Log.d(TAG, "startPreview");                    mCamera.startPreview();                }                else                    result = false;            } catch (Exception e) {                result = false;                e.printStackTrace();            }        }        return result;    }    protected void releaseCamera()    {        synchronized (this)         {            if (mCamera != null)            {                mCamera.stopPreview();                mCamera.setPreviewCallback(null);                mCamera.release();            }            mCamera = null;            if (mFrameChain != null)             {                mFrameChain[0].release();                mFrameChain[1].release();            }            if (mCameraFrame != null)             {                mCameraFrame[0].release();                mCameraFrame[1].release();            }        }    }    private boolean mCameraFrameReady = false;    @Override    protected boolean connectCamera(int width, int height) {        /* 1. We need to instantiate camera         * 2. We need to start thread which will be getting frames         */        /* First step - initialize camera connection */        Log.d(TAG, "Connecting to camera");        if (!initializeCamera(width, height))            return false;        mCameraFrameReady = false;        /* now we can start update thread */        Log.d(TAG, "Starting processing thread");        mStopThread = false;        mThread = new Thread(new CameraWorker());        mThread.start();        return true;    }    @Override    protected void disconnectCamera() {        /* 1. We need to stop thread which updating the frames         * 2. Stop camera and release it         */        Log.d(TAG, "Disconnecting from camera");        try         {            mStopThread = true;            Log.d(TAG, "Notify thread");            synchronized (this) {                this.notify();            }            Log.d(TAG, "Wating for thread");            if (mThread != null)                mThread.join();        }         catch (InterruptedException e)         {            e.printStackTrace();        }         finally         {            mThread =  null;        }        /* Now release camera */        releaseCamera();        mCameraFrameReady = false;    }    @Override    public void onPreviewFrame(byte[] frame, Camera arg1)    {        Log.d(TAG, "Preview Frame received. Frame size: " + frame.length);        synchronized (this)        {            mFrameChain[mChainIdx].put(0, 0, frame);            mCameraFrameReady = true;            this.notify();        }        if (mCamera != null)            mCamera.addCallbackBuffer(mBuffer);    }    private class JavaCameraFrame implements CvCameraViewFrame {        @Override        public Mat gray() {            return mYuvFrameData.submat(0, mHeight, 0, mWidth);        }        @Override        public Mat rgba() {            Imgproc.cvtColor(mYuvFrameData, mRgba, Imgproc.COLOR_YUV2RGBA_NV21, 4);            return mRgba;        }        public JavaCameraFrame(Mat Yuv420sp, int width, int height) {            super();            mWidth = width;            mHeight = height;            mYuvFrameData = Yuv420sp;            mRgba = new Mat();        }        public void release() {            mRgba.release();        }        private Mat mYuvFrameData;        private Mat mRgba;        private int mWidth;        private int mHeight;    };    private class CameraWorker implements Runnable {        @Override        public void run() {            do {                synchronized (JavaCameraView.this) {                    try {                        while (!mCameraFrameReady && !mStopThread)                        {                            JavaCameraView.this.wait();                        }                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    if (mCameraFrameReady)                        mChainIdx = 1 - mChainIdx;                }                if (!mStopThread && mCameraFrameReady) {                    mCameraFrameReady = false;                    if (!mFrameChain[1 - mChainIdx].empty())                        deliverAndDrawFrame(mCameraFrame[1 - mChainIdx]);                }            } while (!mStopThread);            Log.d(TAG, "Finish processing thread");        }    }}

更多相关文章

  1. 代码中设置drawableleft
  2. android 3.0 隐藏 系统标题栏
  3. Android开发中activity切换动画的实现
  4. Android(安卓)学习 笔记_05. 文件下载
  5. Android中直播视频技术探究之—摄像头Camera视频源数据采集解析
  6. 技术博客汇总
  7. android 2.3 wifi (一)
  8. AndRoid Notification的清空和修改
  9. Android中的Chronometer

随机推荐

  1. 1. 变量,常量的区别; 2. 函数的种类与参
  2. 大禹是从死去的男人肚子里蹦出来
  3. 黄帝建国版图与他的足迹
  4. 使用flex、grid跟定位布局仿一个简易的淘
  5. 探秘黄帝与中华文明的起源
  6. CSS伪类选择器、box-sizing属性、常用单
  7. 为什么说网站更新,要有规律?良好的更新频率
  8. 一篇文章告诉你SEO究竟该如何入门?
  9. HTML常用元素样式、定位学习与应用
  10. PHP检查空值的方法总结