开发案例2——可以保存照片的相机

相信通过上一篇博文大家已经熟悉了使用手机照相机的方法,在此基础上,我们通过添加额外的功能就可以开发出适合自己使用的自定义相机应用了,今天我们来完成照相机相片存储的实现。

还是你们喜欢的代码!!!

因为我们要在存储设备上进行读写操作,所以还是要先申请权限,在AndroidManifest.xml文件中增加如下代码:

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

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

然后,我们来创建拍照界面布局,相比于上一个实例,我们这次再添加两个文本框,分别为重拍和保存,来实现我们先期望的功能:

/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"/>

   

     <TextView

        android:id="@+id/button_recamera"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentBottom="true"

        android:layout_alignParentLeft="true"

        android:text="重拍"

        android:textColor="@android:color/white"

        android:textSize="24dp"/>

 

    <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"/>

    <TextView

         android:id="@+id/button_save"

         android:layout_width="wrap_content"

         android:layout_height="wrap_content"

         android:layout_alignParentBottom="true"

         android:layout_alignParentRight="true"

         android:text="保存"

         android:textColor="@android:color/white"

         android:textSize="24dp"/>

</RelativeLayout>

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

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

代码清单:

packagecom.example.androidcamera01;

 

importjava.io.ByteArrayOutputStream;

importjava.io.File;

 

importjava.io.FileOutputStream;

importjava.io.IOException;

importjava.text.SimpleDateFormat;

importjava.util.Date;

 

importjava.util.List;

importandroid.annotation.SuppressLint;

importandroid.app.Activity;

 

importandroid.content.res.Configuration;

importandroid.graphics.Bitmap;

importandroid.graphics.BitmapFactory;

 

importandroid.hardware.Camera;

 

importandroid.hardware.Camera.PictureCallback;

importandroid.hardware.Camera.Size;

importandroid.os.Bundle;

importandroid.os.Environment;

 

importandroid.view.SurfaceHolder;

importandroid.view.SurfaceView;

importandroid.view.View;

importandroid.view.View.OnClickListener;

importandroid.view.WindowManager;

 

importandroid.widget.ImageButton;

 

importandroid.widget.TextView;

importandroid.widget.Toast;

public classMainActivity extends Activity implements SurfaceHolder.Callback{

    //拍照预览

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

    private SurfaceHolder surfaceHolder;//定义控件

    //照相机

    private Camera mCamera;

    //图片地址

    private ImageButton btn_camera;

    private TextView btn_recamera;

    private TextView btn_save;

   

    private byte[] buffer = null;

   

   

    public voidonCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        //设置布局

        setContentView(R.layout.activity_main);

        //禁止自动锁屏

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

       

        //绑定视图

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

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

        btn_save =(TextView) findViewById(R.id.button_save);

        btn_recamera =(TextView) findViewById(R.id.button_recamera);

        //SurfaceView中获得SurfaceHolder

        surfaceHolder = surfaceView.getHolder();

        surfaceHolder.addCallback(this);

        mCamera = isCameraAvailiable();

       

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

        //设置事件监听

        surfaceCreated(surfaceHolder);

        ButtonOnClickListener onClickListener = newButtonOnClickListener();       

        btn_recamera.setOnClickListener(onClickListener);

        btn_camera.setOnClickListener(onClickListener); 

        btn_save.setOnClickListener(onClickListener);

    }//end of onCreate

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

    public static CameraisCameraAvailiable(){

         Camera object = null;

          try {

            object = Camera.open();

         }

          catch(Exception e){    

         }

          return object;

       }

 

 

    class  ButtonOnClickListener implementsOnClickListener{

 

        @Override

        public voidonClick(View v) {

            // TODOAuto-generated method stub

            switch (v.getId()){ 

           case R.id.button_camera: {

            mCamera.takePicture(null, null, capturedIt);

            btn_camera.setVisibility(View.INVISIBLE);

            btn_recamera.setVisibility(View.VISIBLE);

            btn_save.setVisibility(View.VISIBLE);

            break;}

           case R.id.button_recamera:{

            mCamera.startPreview();

            btn_camera.setVisibility(View.VISIBLE);

            btn_recamera.setVisibility(View.INVISIBLE);

            btn_save.setVisibility(View.INVISIBLE);

            break;

           }

           case R.id.button_save:{       

               saveImageToFile();

            btn_camera.setVisibility(View.INVISIBLE);

            btn_recamera.setVisibility(View.VISIBLE);

            btn_save.setVisibility(View.INVISIBLE);

            break;

            }

          }

        }  

       }//end ofclass ButtonOnClickListener

 

    //picture显示

    private PictureCallback capturedIt = newPictureCallback() {

 

        @Override

        public voidonPictureTaken(byte[] data, Camera camera) {

               

       Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data .length);

        if(bitmap==null){         

        }

        else

       {    ByteArrayOutputStream baos = newByteArrayOutputStream();

         bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

            buffer = new byte[baos.toByteArray().length];

            buffer = baos.toByteArray().clone();}          

    }

};//end ofclass PictureCallback

   

    private voidsaveImageToFile(){

         File file = getOutFile();

          if (file == null){

             Toast.makeText(getApplicationContext(), "文件创建失败,请检查SD卡读写权限", Toast.LENGTH_SHORT).show();

             return ;

         }

       

          if (buffer == null){

             

         }else{

             try{

                 FileOutputStream fos = newFileOutputStream(file);

                 fos.write(buffer);

                 fos.flush();

                 fos.close();

             }catch(IOException e){

                 e.printStackTrace();

             }

         }

        }//end ofsaveImageToFile

   

    private File getOutFile() {

        // TODOAuto-generated method stub

          String storageState = Environment.getExternalStorageState();

         if(Environment.MEDIA_REMOVED.equals(storageState)){

            Toast.makeText(getApplicationContext(), "oh,no, SD卡不存在", Toast.LENGTH_SHORT).show();

            return null;

         }

         

        File mediaStorageDir = new File(Environment

                .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)

                ,"MyPictures");

         if (!mediaStorageDir.exists()){

            if (!mediaStorageDir.mkdirs()){

                return null;

            }

         }

         

        File file = new File(setFilePath(mediaStorageDir));

         

         return file;

    }//end of getOutFile

   

    @SuppressLint("SimpleDateFormat")

    private StringsetFilePath(File mediaStorageDir) {

        // TODOAuto-generated method stub

        String timeStamp =newSimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());

       String filePath = mediaStorageDir.getPath()+ File.separator;

        filePath += (timeStamp + ".jpg");

      return filePath;

    }//end of getFilePath

   

   

@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);

                 //对于Android2.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();

            System.out.println("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

        }

}

 

 

有保存图片功能的相机很明显,从字面上我们就知道应该添加保存图片的功能,相比于上一个简单的相机的代码,这个实例的代码增加的部分主要是:

1.   按键的监听和处理;

本开发案例要实现拍照功能,保存图片的功能,以及保存后在进入拍照状态。所以我们在界面中添加了三个按钮,对这三个事件源添加事件监听从而实现我们想要的功能。这部分内容是Android开发的基础,再次不做赘述。

2.   实现PictureCallback接口,重写onPictureTaken方法:

这里引入了BitMap类,Bitmap是Android系统中的图像处理的最重要类之一。用它可以获取图像文件信息,进行图像剪切、旋转、缩放等操作,并可以指定格式保存图像文件。

更多介绍请参见文档

 http://www.open-open.com/lib/view/open1333418945202.html

public voidonPictureTaken(byte[] data, Camera camera) {

//将频幕当前图像转换成Bitmap对象        

Bitmap bitmap =BitmapFactory.decodeByteArray(data , 0, data .length);

      

//字节输出流,用于存放图片字节流   

 ByteArrayOutputStream baos = newByteArrayOutputStream();

//输出格式设置

bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

//第你一一片缓存区,存储图片,用于预览

buffer = new byte[baos.toByteArray().length];

buffer = baos.toByteArray().clone();}         

}

 

3.   存储文件

这部分就涉及到Android开放当中文件操作的部分了,在这里我们用了两个方法完成了设置存储文件的名称,存储路径,将文件存储到设置好的路径下:

private voidsaveImageToFile(){… …}

private File getOutFile() {… …}

 

文件读写部分我会在Android开发文件操作部分进行详细说明的部分。

 

 

效果图:

  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值