zoukankan      html  css  js  c++  java
  • Android 创建自己的Camera App

    在sdk中找到/sdk/docs/guide/topics/media/camera.html#custom-camera,里面有详细的api参考

    在清单文件中添加相应的权限:

        
        <uses-permission android:name="android.permission.CAMERA" />
        <uses-feature android:name="android.hardware.camera" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.RECORD_AUDIO" />
        

    按照官方文档,分为下面几步:

    • Detect and Access Camera - Create code to check for the existence of cameras and request access.
    • Create a Preview Class - Create a camera preview class that extends SurfaceView and implements theSurfaceHolder interface. This class previews the live images from the camera.
    • Build a Preview Layout - Once you have the camera preview class, create a view layout that incorporates the preview and the user interface controls you want.
    • Setup Listeners for Capture - Connect listeners for your interface controls to start image or video capture in response to user actions, such as pressing a button.
    • Capture and Save Files - Setup the code for capturing pictures or videos and saving the output.
    • Release the Camera - After using the camera, your application must properly release it for use by other applications.

    接下来分别实现:

    1、检查设备是否有照相机

        /** 检查设备是否存在照相机 */
        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;
            }
        }
        

    2、得到一个照相机

     /** 一种安全的方式获取Cameer对象的实例. */
        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
        }

    3、新建一个名为CameraPreview的类

    package com.wuyudong.mycamera;
    
    import java.io.IOException;
    
    import android.content.Context;
    import android.hardware.Camera;
    import android.util.Log;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    
    /** A basic Camera preview class */
    public class CameraPreview extends SurfaceView implements
            SurfaceHolder.Callback {
        private static final String TAG = "CameraPreview";
        private SurfaceHolder mHolder;
        private Camera mCamera;
    
        public CameraPreview(Context context, Camera camera) {
            super(context);
            mCamera = camera;
    
            // Install a SurfaceHolder.Callback so we get notified when the
            // underlying surface is created and destroyed.
            mHolder = getHolder();
            mHolder.addCallback(this);
            // deprecated setting, but required on Android versions prior to 3.0
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
    
        public void surfaceCreated(SurfaceHolder holder) {
            // The Surface has been created, now tell the camera where to draw the
            // preview.
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
                Log.d(TAG, "Error setting camera preview: " + e.getMessage());
            }
        }
    
        public void surfaceDestroyed(SurfaceHolder holder) {
            // empty. Take care of releasing the Camera preview in your activity.
        }
    
        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            // If your preview can change or rotate, take care of those events here.
            // Make sure to stop the preview before resizing or reformatting it.
    
            if (mHolder.getSurface() == null) {
                // preview surface does not exist
                return;
            }
    
            // stop preview before making changes
            try {
                mCamera.stopPreview();
            } catch (Exception e) {
                // ignore: tried to stop a non-existent preview
            }
    
            // set preview size and make any resize, rotate or
            // reformatting changes here
    
            // start preview with new settings
            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();
    
            } catch (Exception e) {
                Log.d(TAG, "Error starting camera preview: " + e.getMessage());
            }
        }
    }

    4、设置一个预览功能的layout,将原来布局文件中的内容替换成下面的代码

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
      <FrameLayout
        android:id="@+id/camera_preview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        />
    
      <Button
        android:id="@+id/button_capture"
        android:text="Capture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        />
    </LinearLayout>

    5、在清单文件中加入 android:screenOrientation="landscape" 调整相机为横向拍摄

    6、在MainActivity中添加

    public class MainActivity extends Activity {
    
        private Camera mCamera;
        private CameraPreview mPreview;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            // Create an instance of Camera
            mCamera = getCameraInstance();
    
            // Create our Preview view and set it as the content of our activity.
            mPreview = new CameraPreview(this, mCamera);
            FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
            preview.addView(mPreview);
        }
    }

    7、实现拍摄按钮的功能

    (1)添加拍照回调方法

        private PictureCallback mPicture = new PictureCallback() {
    
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
    
                File pictureFile = new File("/sdcard/" + System.currentTimeMillis()+".jpg");
                try {
                    FileOutputStream fos = new FileOutputStream(pictureFile);
                    fos.write(data);
                    fos.close();
                } catch (IOException e) {
                    Log.d("TAG", "Error accessing file: " + e.getMessage());
                }
            }
        };

    给拍照按钮添加注册事件:

            // Add a listener to the Capture button
            Button captureButton = (Button) findViewById(R.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);
                    }
                }
            );

    完整的代码如下:

    package com.wuyudong.mycamera;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.sql.Date;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.content.Context;
    import android.content.pm.PackageManager;
    import android.hardware.Camera;
    import android.hardware.Camera.AutoFocusCallback;
    import android.hardware.Camera.PictureCallback;
    import android.util.Log;
    import android.view.Menu;
    import android.view.View;
    import android.widget.Button;
    import android.widget.FrameLayout;
    
    public class MainActivity extends Activity {
    
        private Camera mCamera;
        private CameraPreview mPreview;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // 创建一个 Camera 的实例
            mCamera = getCameraInstance();
    
            // 创建一个预览界面
            mPreview = new CameraPreview(this, mCamera);
            FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
            preview.addView(mPreview);
            
            // Add a listener to the Capture button
            Button captureButton = (Button) findViewById(R.id.button_capture);
            captureButton.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mCamera.autoFocus(new AutoFocusCallback() {  // 对焦
                            
                            @Override
                            public void onAutoFocus(boolean success, Camera camera) {
                                // get an image from the camera
                                mCamera.takePicture(null, null, mPicture);
                                
                            }
                        });
                        
                    }
                }
            );
        }
    
        /** 检查设备是否存在照相机 */
        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;
            }
        }
    
        /** 一种安全的方式获取Cameer对象的实例. */
        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
        }
        
        private PictureCallback mPicture = new PictureCallback() {
    
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
    
                File pictureFile = new File("/sdcard/" + System.currentTimeMillis()+".jpg");
                try {
                    FileOutputStream fos = new FileOutputStream(pictureFile);
                    fos.write(data);
                    fos.close();
                } catch (IOException e) {
                    Log.d("TAG", "Error accessing file: " + e.getMessage());
                }
            }
        };
        
        protected void onDestory() {
            if(mCamera != null) {    //释放资源
                mCamera.release();
                mCamera = null;
            }
        }
    
    }
  • 相关阅读:
    案例(用封装的ajax加载数据库的数据到页面)
    案例(用封装的ajax函数检查用户名)
    Verilog中的UDP
    FPGA中的“门”
    反馈的基础概述
    集成运放四种组态
    阻抗匹配处理方式
    关于阻抗匹配的理解
    关于输入阻抗和输出阻抗的理解
    电压跟随器的一点理解
  • 原文地址:https://www.cnblogs.com/wuyudong/p/5853877.html
Copyright © 2011-2022 走看看