Android API之CameraPreview

来源:互联网 发布:怎么查询域名是否备案 编辑:程序博客网 时间:2024/05/17 22:22
@SuppressWarnings("deprecation")public class CameraPreview extends Activity {    private Preview mPreview;    Camera mCamera;    int numberOfCameras;    int cameraCurrentlyLocked;    int defaultCameraId;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //设置全屏显示        requestWindowFeature(Window.FEATURE_NO_TITLE);        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);        //初始化界面        mPreview = new Preview(this);        setContentView(mPreview);        //找到可用的相机数量        numberOfCameras = Camera.getNumberOfCameras();        // 查找默认相机的标识        CameraInfo cameraInfo = new CameraInfo();        for (int i = 0; i < numberOfCameras; i++) {            Camera.getCameraInfo(i, cameraInfo);            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {                defaultCameraId = i;            }        }    }    @Override    protected void onResume() {        super.onResume();        // 打开默认的即第一个后置摄像头。        mCamera = Camera.open();        cameraCurrentlyLocked = defaultCameraId;        mPreview.setCamera(mCamera);    }    @Override    protected void onPause() {        super.onPause();        //不使用地时候需要释放 资源        if (mCamera != null) {            mPreview.setCamera(null);            mCamera.release();            mCamera = null;        }    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        MenuInflater inflater = getMenuInflater();        inflater.inflate(R.menu.camera_menu, menu);        return true;    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        switch (item.getItemId()) {        case R.id.switch_cam:            if (numberOfCameras == 1) {                AlertDialog.Builder builder = new AlertDialog.Builder(this);                builder.setMessage(this.getString(R.string.camera_alert))                        .setNeutralButton("Close", null);                AlertDialog alert = builder.create();                alert.show();                return true;            }            if (mCamera != null) {                mCamera.stopPreview();                mPreview.setCamera(null);                mCamera.release();                mCamera = null;            }            mCamera = Camera                    .open((cameraCurrentlyLocked + 1) % numberOfCameras);            cameraCurrentlyLocked = (cameraCurrentlyLocked + 1)                    % numberOfCameras;            mPreview.switchCamera(mCamera);            mCamera.startPreview();            return true;        default:            return super.onOptionsItemSelected(item);        }    }}/** * 自定义 ViewGroup:简单的包装在一个摄像头和一个图形渲染一个中心预览相机表面。 * 我们利用SurfaceView来处理预览,因为并不是所有的设备有摄像头,支持预览大小相同的纵横比为设备的显示。 */@SuppressWarnings("deprecation")class Preview extends ViewGroup implements SurfaceHolder.Callback {    private final String TAG = "Preview";    // 预览画面的SurfaceView    SurfaceView mSurfaceView;    // SurfaceHolder接:控制surface的大小和格式, 在surface上编辑像素及监视surace的改变等 。    SurfaceHolder mHolder;    // 预览画面的大小    Size mPreviewSize;    List<Size> mSupportedPreviewSizes;    // 相机    Camera mCamera;    Preview(Context context) {        super(context);        mSurfaceView = new SurfaceView(context);        //添加View        addView(mSurfaceView);        //初始化SurfaceHolder        mHolder = mSurfaceView.getHolder();        //绑定监听接口        mHolder.addCallback(this);        //设置类型        //SURFACE_TYPE_PUSH_BUFFERS表明该Surface不包含原生数据,Surface用到的数据由其他对象提供,        //在Camera图像预览中就使用该类型的Surface,有Camera负责提供给预览Surface数据,这样图像预览会比较流畅        //http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1201/656.html        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);    }    // 相机设置    public void setCamera(Camera camera) {        mCamera = camera;        if (mCamera != null) {            // 获取摄像头所支持的所有分辨率            mSupportedPreviewSizes = mCamera.getParameters()                    .getSupportedPreviewSizes();            requestLayout();        }    }    public void switchCamera(Camera camera) {        setCamera(camera);        try {            //设置预览展示            camera.setPreviewDisplay(mHolder);        } catch (IOException exception) {            Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);        }        //获取相机配置 参数         Camera.Parameters parameters = camera.getParameters();        //设置预览大小        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);        requestLayout();        //给相机设置参数        camera.setParameters(parameters);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        //摄像头不是所有随便的(w, h)都能够认识的,所以在onMeasure()方法中进行处理        final int width = resolveSize(getSuggestedMinimumWidth(),                widthMeasureSpec);        final int height = resolveSize(getSuggestedMinimumHeight(),                heightMeasureSpec);        setMeasuredDimension(width, height);        if (mSupportedPreviewSizes != null) {            mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width,                    height);        }    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        if (changed && getChildCount() > 0) {            final View child = getChildAt(0);            final int width = r - l;            final int height = b - t;            int previewWidth = width;            int previewHeight = height;            if (mPreviewSize != null) {                previewWidth = mPreviewSize.width;                previewHeight = mPreviewSize.height;            }            if (width * previewHeight > height * previewWidth) {                final int scaledChildWidth = previewWidth * height                        / previewHeight;                child.layout((width - scaledChildWidth) / 2, 0,                        (width + scaledChildWidth) / 2, height);            } else {                final int scaledChildHeight = previewHeight * width                        / previewWidth;                child.layout(0, (height - scaledChildHeight) / 2, width,                        (height + scaledChildHeight) / 2);            }        }    }    public void surfaceCreated(SurfaceHolder holder) {        try {            if (mCamera != null) {                mCamera.setPreviewDisplay(holder);            }        } catch (IOException exception) {            Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);        }    }    public void surfaceDestroyed(SurfaceHolder holder) {        if (mCamera != null) {            mCamera.stopPreview();        }    }    //获取最佳的拍照或录像预览窗口大小     private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {        final double ASPECT_TOLERANCE = 0.1;        double targetRatio = (double) w / h;        if (sizes == null)            return null;        Size optimalSize = null;        double minDiff = Double.MAX_VALUE;        int targetHeight = h;        // 试着找到一个尺寸匹配的纵横比和尺寸        for (Size size : sizes) {            double ratio = (double) size.width / size.height;            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)                continue;            if (Math.abs(size.height - targetHeight) < minDiff) {                optimalSize = size;                minDiff = Math.abs(size.height - targetHeight);            }        }        // 找不到一个匹配的纵横比,进行处理        if (optimalSize == null) {            minDiff = Double.MAX_VALUE;            for (Size size : sizes) {                if (Math.abs(size.height - targetHeight) < minDiff) {                    optimalSize = size;                    minDiff = Math.abs(size.height - targetHeight);                }            }        }        return optimalSize;    }    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {        //预览大小是已知的,设置相机参数,并开始预览。        Camera.Parameters parameters = mCamera.getParameters();        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);        requestLayout();        mCamera.setParameters(parameters);        mCamera.startPreview();    }}
0 0
原创粉丝点击