Android Camera 相机程序编写

要自己写一个相机应用直接使用相机硬件,首先应用需要一个权限设置,在AndroidManifest.xml中加上使用设备相机的权限

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

 

 

  为你的应用创建自定义的相机,一般步骤如下:

  1.检测相机硬件并获取访问

  2.建立一个Preview类:需要一个相机预览的类,继承 SurfaceView 类,并实现SurfaceHolder接口。

  3.建立预览的布局。

  4.为拍照建立监听。

  5.拍照并且存储文件。

  6.释放相机。

  因为相机是一个共享资源,所以应该被谨慎管理,这样应用之间才不会发生冲突。

  所以使用完相机之后应该调用 Camera.release()来释放相机对象。

  如果不释放,后续的使用相机请求(其他应用或本应用)都会失败。

 

检测相机硬件

  如果你的程序没有在manifest的声明中要求有相机,那么你应该在运行时检查相机的存在与否,主要用了 PackageManager.hasSystemFeature() 方法。比如:

复制代码
    /** Check if this device has a camera */
    private boolean checkCameraHardware(Context context)
    {
        if (context.getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_CAMERA))
        {
            // this device has a camera
            return true;
        }
        else
        {
            // no camera on this device
            return false;
        }
    }
复制代码

 

 

  设备上可能有多个相机,Android 2.3以后可以使用 Camera.getNumberOfCameras()来查看相机的数目。

  如下面这段程序用于检测设备中的相机,并得到默认相机的索引号:

复制代码
    private int getDefaultCameraId()
    {
        int defaultId = -1;

        // Find the total number of cameras available
        mNumberOfCameras = Camera.getNumberOfCameras();

        // Find the ID of the default camera
        CameraInfo cameraInfo = new CameraInfo();
        for (int i = 0; i < mNumberOfCameras; i++)
        {
            Camera.getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK)
            {
                defaultId = i;
            }
        }
        if (-1 == defaultId)
        {
            if (mNumberOfCameras > 0)
            {
                // 如果没有后向摄像头
                defaultId = 0;
            }
            else
            {
                // 没有摄像头
                Toast.makeText(getApplicationContext(), R.string.no_camera,
                        Toast.LENGTH_LONG).show();
            }
        }
        return defaultId;
    }
复制代码

 

  看了Camera类的代码实现后,其中不带参数的open()方法

复制代码
    public static Camera open()
    {
        int numberOfCameras = getNumberOfCameras();
        CameraInfo cameraInfo = new CameraInfo();
        for (int i = 0; i < numberOfCameras; i++)
        {
            getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK)
            {
                return new Camera(i);
            }
        }
        return null;
    }
复制代码

 

  说明open方法默认是打开第一个后向摄像头的。

 

访问相机

  当检测到设备上有相机之后,必须获取其访问权,获取一个 Camera 类的对象。

  要获取主要的相机,可以使用 Camera.open() 方法,注意异常处理。

  在使用这个方法的时候一定要检查异常,如果相机正在被使用或者不存在,没有处理异常,将会使得应用被系统关闭。

  如:

复制代码
    /** A safe way to get an instance of the Camera object. */
    public static Camera getCameraInstance()
    {
        Camera c = null;
        try
        {
            c = Camera.open(); // attempt to get a Camera instance
        }
        catch (Exception e)
        {
            // Camera is not available (in use or does not exist)
        }
        return c; // returns null if camera is unavailable
    }
复制代码

 

  Android 2.3之后,可以使用Camera.open(int)来获取特定的相机。

 

检查相机特性

  可以使用Camera.getParameters()方法来检查相机的特性。

  API Level 9之后,可以使用 Camera.getCameraInfo()来查看相机是在设备前面还是后面,还可以得到图像的方向。

 

建立Preview类

  为了有效地拍照或录像,用户必须要看到相机能看到的图像。

  相机的preview类是一个 SurfaceView ,展示了相机正在捕捉的图像。

  下面是一个预览类的例子(来自官网):

A basic preview class

  注意要设置尺寸的话需要放在surfaceChanged()方法里,调用 setPreviewSize()方法,并且应该使用 getSupportedPreviewSizes()返回的值,而不要使用任意的尺寸。

 

把Preview放在布局里面

  布局时可以使用FrameLayout,这样其他的按钮或者元素可以叠加在预览图像上。

  对于大多数设备来说,相机预览的默认方向是横放的(landscape)。

  从Android 2.2 (API Level 8)开始,可以使用 setDisplayOrientation()来设置预览图像的方向。

  如果需要在用户改变设备方向的时候改变预览图像的方向,可以在 surfaceChanged()方法中,首先用 Camera.stopPreview() 停止预览,改变方向,然后用Camera.startPreview()开启新的预览。

  当然你也可以直接在manifest中设置好方向,如下:

复制代码
<activity android:name=".CameraActivity"
          android:label="@string/app_name"

          android:screenOrientation="landscape">
          <!-- configure this activity to use landscape orientation -->

          <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
复制代码

 

拍照

  在应用里面,必须为用户控制加上监听,来响应用户拍照的动作。

  为了得到图像,要使用 Camera.takePicture()方法。

  这个方法接收三个参数,用于从相机获取图像。

  为了接收到JPEG格式的数据,需要实现Camera.PictureCallback接口用来接收图像数据并且写入文件。

  下面的代码展示了一个最基本的实现:

复制代码
private PictureCallback mPicture = new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {

        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
        if (pictureFile == null){
            Log.d(TAG, "Error creating media file, check storage permissions: " +
                e.getMessage());
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }
};
复制代码

 

 

  照相动作可以用按钮控制,如下:

复制代码
// Add a listener to the Capture button
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
    new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // get an image from the camera
            mCamera.takePicture(null, null, mPicture);
        }
    }
);
复制代码

 

 

释放相机

  相机是设备资源,被所有应用共享,当应用不使用相机时应当及时释放,应当在Activity.onPause()中释放。

  如果不及时释放,后续的相机请求(包括你自己的应用和其他的应用发出的)都将失败并且导致应用退出。

 

 

实验程序

  完整的照相程序需要考虑相机切换、预览图像的尺寸设置、焦距变换、缩放、白平衡的相机参数设置。

  请查阅文后的参考资料进行进一步学习。

  附上一个粗糙待完善的自定义相机程序(2013/4/6)

  预览图像类: 

CameraPreview

  主要的Activity类:

HelloCustomCameraActivity

  布局文件:

activity_hello_custom_camera.xml

  Manifest文件:

AndroidManifest.xml

 

 

 

  三星S5660上测试可以拍照用,其他手机未知。

  

 

参考资料

  Reference: Camera

  http://developer.android.com/reference/android/hardware/Camera.html

  相机参数:

  http://developer.android.com/reference/android/hardware/Camera.Parameters.html

  API Guides: Camera

  http://developer.android.com/guide/topics/media/camera.html

  API Demos:

  com.example.android.apis.graphics包下的CameraPreview

  实例教程:Android设备功能之Camera教程篇:

  http://www.eoeandroid.com/thread-167870-1-1.html

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值