Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能

来源:互联网 发布:网络犯罪特搜班土豆 编辑:程序博客网 时间:2024/05/03 08:55

Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能


Android Camera开发系列(上)——Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片

上篇讲的都是一些基本的使用,这篇就来自己定义一个相机了

参照Google API:http://developer.android.com/guide/topics/media/camera.html

我们还是在原来的demo上修改,新增一个button,点击跳转到CameraActivity,我们在CameraActivity内实现我们的自定义相机,这里值得注意的是,我们拍照时要一直捕捉拍照的过程,普通的view肯定不行,google给我们提供了一个view叫做

这里写图片描述

一.获取相机

这里有个前提,记得添加权限

<uses-permission android:name="android.permission.CAMERA"/>

我们新增一个方法来获取系统的相机实例

/**     * 获取系统相机     *      * @return     */    private Camera getcCamera() {        Camera camera = null;        try {            camera = Camera.open();        } catch (Exception e) {            camera = null;        }        return camera;    }

这里值得注意的是,camera是废弃的对象,那是因为google新给出来一个新的api

这里写图片描述

但是其实新出的api只是作为高级使用的时候才会用,一般来讲,我们还是用回以前的api

二.SurfaceView预览

要使用SurfaceView还是要

implements SurfaceHolder.Callback

activity_camera.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <SurfaceView        android:id="@+id/sv"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1" />    <Button        android:id="@+id/btn_camera"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="拍照" /></LinearLayout>

预览图像

/**     * 与SurfaceView传播图像     */    private void showViews(Camera camera, SurfaceHolder holder) {        // 预览相机,绑定        try {            camera.setPreviewDisplay(holder);            // 系统相机默认是横屏的,我们要旋转90°            camera.setDisplayOrientation(90);            // 开始预览            camera.startPreview();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }

释放占用内存

/**     * 释放相机的内存     */    private void clearCamera() {        // 释放hold资源        if (mCamera != null) {            // 停止预览            mCamera.stopPreview();            mCamera.setPreviewCallback(null);            // 释放相机资源            mCamera.release();            mCamera = null;        }    }

绑定生命周期

@Override    protected void onResume() {        // TODO Auto-generated method stub        super.onResume();        // 在activity运行时绑定        if (mCamera == null) {            mCamera = getcCamera();            if (sh != null) {                showViews(mCamera, sh);            }        }    }    @Override    protected void onPause() {        // TODO Auto-generated method stub        super.onPause();        // activity暂停时我们释放相机内存        clearCamera();    }

SurfaceView回调并同步预览

@Override    public void surfaceCreated(SurfaceHolder holder) {        // 开始预览        showViews(mCamera, sh);    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width,            int height) {        // 重启功能        mCamera.stopPreview();        showViews(mCamera, sh);    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        // 释放        clearCamera();    }

写到这里,基本上我们的可以预览了,我们来运行一下

这里写图片描述

这里因为是模拟器,他只有前置摄像头,本应该旋转270°的,我们只要知道通过以上的方法可以同步预览影像就可以了

拍照保存图片

我们设置拍照这个button的点击事件

btn_camera = (Button) findViewById(R.id.btn_camera);        btn_camera.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                // 获取当前相机参数                Camera.Parameters parameters = mCamera.getParameters();                // 设置相片格式                parameters.setPictureFormat(ImageFormat.JPEG);                // 设置预览大小                parameters.setPreviewSize(800, 480);                // 设置对焦方式,这里设置自动对焦                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);                mCamera.autoFocus(new AutoFocusCallback() {                    @Override                    public void onAutoFocus(boolean success, Camera camera) {                        // 判断是否对焦成功                        if (success) {                            // 拍照 第三个参数为拍照回调                            mCamera.takePicture(null, null, pc);                        }                    }                });            }        });

这里的pc是一个回调方法,我们重写

private PictureCallback pc = new PictureCallback() {        @Override        public void onPictureTaken(byte[] data, Camera camera) {            // data为完整数据            File file = new File("/sdcard/photo.png");            // 使用流进行读写            try {                FileOutputStream fos = new FileOutputStream(file);                try {                    fos.write(data);                    // 关闭流                    fos.close();                    // 查看图片                    Intent intent = new Intent(CameraActivity.this,                            PhotoActivity.class);                    // 传递路径                    intent.putExtra("path", file.getAbsolutePath());                    startActivity(intent);                    finish();                } catch (IOException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            } catch (FileNotFoundException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    };

查看图片

我们拍完照片然后就跳转到PhotoActivity查看图片

activity_photo.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <TextView        android:id="@+id/tv_path"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <ImageView        android:id="@+id/iv_photo"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /></LinearLayout>

PhotoActivity

package com.lgl.camera;import java.io.FileInputStream;import java.io.FileNotFoundException;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Matrix;import android.os.Bundle;import android.widget.ImageView;import android.widget.TextView;public class PhotoActivity extends Activity {    private TextView tv_path;    private ImageView iv_photo;    @Override    protected void onCreate(Bundle savedInstanceState) {        // TODO Auto-generated method stub        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_photo);        String path = getIntent().getStringExtra("path");        tv_path = (TextView) findViewById(R.id.tv_path);        // 显示路径        tv_path.setText(path);        iv_photo = (ImageView) findViewById(R.id.iv_photo);        // 调整角度        try {            FileInputStream fis = new FileInputStream(path);            Bitmap bitmap = BitmapFactory.decodeStream(fis);            // 矩阵            Matrix matrix = new Matrix();            matrix.setRotate(90);            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),                    bitmap.getHeight(), matrix, true);            iv_photo.setImageBitmap(bitmap);        } catch (FileNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

我们运行一下
拍完之后跳转到PhotoActivity界面

这里写图片描述

但是相机是一个大坑,各种不兼容,而且还有前后置摄像头之分哟,上面代码病没有提及前置,前置需要翻转270°,并且我们之前就应该判断是否是前置,再进行旋转,这个只是初学的示例代码,有兴趣的可以下载demo玩玩

Demo下载地址:http://download.csdn.net/detail/qq_26787115/9419048

3 0
原创粉丝点击