开发案例1——简单的相机实现

现在,我们来实现一个简单的Android手机拍照的实例。

该实例只是将Camera最基本的功能连接起来,即能够预览,将摄像头与手机屏幕联系起来。重在解释原理。如果想开发功能完善的相机应用,还需要添加更多功能代码。请继续关注博主的后续关于Android相机那点事儿的更新。

你们最喜欢的代码来啦!!!

首先我们应该授予程序是用摄像头的权限,所以在AndroidManifest.xml文件中增加如下代码:

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

<uses-feature android:name="android.hardware.camera" />

<uses-feature android:name="android.hardware.camera.autofocus" />

然后,我们建立一个简单的拍照界面布局:

/AndroidCamera01/res/layout/activity_main.xml

代码清单:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/Linear01"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent">

   

    <SurfaceView

       android:id="@+id/surfCamera"

       android:layout_width="fill_parent"

       android:layout_height="fill_parent"/>

 

    <ImageButton

        android:id="@+id/button_camera"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerHorizontal="true"

        android:layout_alignParentBottom="true"

        android:background="#00000000"

        android:src="@drawable/button"/>

 

</RelativeLayout>

 

 

最后,我们来编写最重要的MainActivity.java文件

/AndroidCamera01/src/com/example/androidcamera01/MainActivity.java

代码清单:

packagecom.example.androidcamera01;

 

importjava.io.IOException;

importjava.util.List;

importandroid.app.Activity;

importandroid.content.res.Configuration;

importandroid.hardware.Camera;

importandroid.hardware.Camera.PictureCallback;

importandroid.hardware.Camera.Size;

importandroid.os.Bundle;

importandroid.view.SurfaceHolder;

importandroid.view.SurfaceView;

importandroid.view.View;

importandroid.view.View.OnClickListener;

importandroid.view.WindowManager;

importandroid.widget.ImageButton;

importandroid.widget.Toast;

 

public classMainActivity extends Activity implementsSurfaceHolder.Callback {

    //拍照预览

    private SurfaceView surfaceView;//定义视图控件

    private SurfaceHolder surfaceHolder;//定义控件

    //照相机

    private Camera mCamera;

    //图片地址

    private ImageButton btn_camera;

   

    public voidonCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        //设置布局

        setContentView(R.layout.activity_main);

        //绑定视图

        surfaceView =(SurfaceView) findViewById(R.id.surfCamera);

        btn_camera =(ImageButton) findViewById(R.id.button_camera);

      

      //SurfaceView中获得SurfaceHolder

          surfaceHolder = surfaceView.getHolder();

          surfaceHolder.addCallback(this);

        surfaceHolder.setType(surfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

       

        mCamera = isCameraAvailiable();

        if(mCamera==null) Toast.makeText(getApplicationContext(),"相机设备被占用", Toast.LENGTH_SHORT).show();    

       

        //设置事件监听               btn_camera.setOnClickListener(new OnClickListener() {

           

            @Override

            public voidonClick(View v) {

                // TODOAuto-generated method stub

                mCamera.takePicture(null, null, capturedIt);

            }

        });                                                                    

    }//end of onCreate

   

    //判断照相机设备是否可用

    public static CameraisCameraAvailiable(){

         Camera object = null;

          try {

            object = Camera.open();

         }

          catch(Exception e){    

         }

          return object;

       }

 

//picture显示

    private PictureCallback capturedIt = newPictureCallback() {

 

        @Override

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

               

        }

};//end ofclass PictureCallback       

   

@Override

       public voidsurfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {

   

       }

 

@Override

       public voidsurfaceCreated(SurfaceHolder holder) {

          try   {

         Camera.Parameters parameters = mCamera.getParameters();

         

         if(this.getResources().getConfiguration().orientation!=Configuration.ORIENTATION_LANDSCAPE)

         {            

              parameters.set("orientation", "portrait");

              mCamera.setDisplayOrientation(90);

              parameters.setRotation(90);   

         }else {

                 parameters.set("orientation", "landscape");

                 //对于Android 2.2及以上版本

                 mCamera.setDisplayOrientation(0);

                 //对于Android 2.2及以上版本取消注释

                 parameters.setRotation(0);

            }         

            Size largestSize =getBestSupportedSize(parameters.getSupportedPreviewSizes());

            parameters.setPreviewSize(largestSize.width, largestSize.height);// 设置预览图片尺寸 

            parameters.setPictureSize(largestSize.width, largestSize.height);         

            mCamera.setParameters(parameters);

            mCamera.setPreviewDisplay(holder);            

            mCamera.startPreview();

         } catch (IOException e) {

            mCamera.release();

         }              

       }

 

@Override

       public voidsurfaceDestroyed(SurfaceHolder arg0) {

               mCamera.stopPreview();

               mCamera.release();

   

       }

 

private SizegetBestSupportedSize(List<Size> sizes) { 

            // 取能适用的最大的SIZE 

            Size largestSize = sizes.get(0); 

            int largestArea = sizes.get(0).height * sizes.get(0).width

            for (Size s : sizes) { 

                int area = s.width * s.height

                if (area > largestArea) { 

                    largestArea = area

                    largestSize = s

                } 

            }

            return largestSize

        }

    }

最后谈几点注意事项:

要理解Camera,SurfaceView和SurfaceHolder三者的意义,SurfaceHolder是一个接口,通过SurfaceView类实现,其三个回调方法在是进行将相机参数设置以及和预览容器相连接的重要方法;当进行相机参数设置时要先实例化Camera,然后实例化camera.Preview对象对相机参数进行设置。

要注意相机预览尺寸和照片尺寸一致,否则会出现照相时看到的图片并非真实存储到本地的照片,这样就很尴尬了。这段代码当中的getBestSupportedSize(List<Size> sizes)方法就是用来寻找最适合的尺寸,使相机预览尺寸和照片尺寸保持一致的方法,Android手机都会提供多个照片和预览的尺寸,这些尺寸可能和手机屏幕一致,也可能不一致,因机型不同而定,所以在实际开发时要注意这个问题。具体如何解决,我会在后续的系列博文中和大家分享我在开发是遇到的问题。

本文中的代码只是简单的实现预览,旨在向大家展示Android相机开发的最基本原理。希望对大家的开发有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值