一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Android自定义相机实现定时拍照功能

时间:2017-02-28 编辑:简简单单 来源:一聚教程网

这篇博客为大家介绍Android自定义相机,并且实现倒计时拍照功能。
首先自定义拍照会用到SurfaceView控件显示照片的预览区域,以下是布局文件:
activity_main.xml

 

 代码如下复制代码

  android:layout_width="match_parent"

  android:layout_height="match_parent">

  

  

    android:id="@+id/surface_view"

    android:layout_width="match_parent"

    android:layout_height="match_parent"/>

  

  

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical">

  

    

      android:id="@+id/start"

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"

      android:layout_centerHorizontal="true"

      android:layout_alignParentBottom="true"

      android:layout_marginBottom="10dp"

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

  

    

      android:id="@+id/count_down"

      android:layout_width="match_parent"

      android:layout_height="match_parent"

      android:layout_gravity="center"

      android:gravity="center"

      android:textSize="80sp"/>

  

 

MainActivity.java

 

 代码如下复制代码

packagecom.jackie.timercamera;

  

importandroid.content.Context;

importandroid.graphics.Bitmap;

importandroid.graphics.BitmapFactory;

importandroid.graphics.Matrix;

importandroid.hardware.Camera;

importandroid.media.AudioManager;

importandroid.media.MediaPlayer;

importandroid.net.Uri;

importandroid.os.Bundle;

importandroid.os.Environment;

importandroid.os.Handler;

importandroid.support.v7.app.AppCompatActivity;

importandroid.util.Log;

importandroid.view.SurfaceHolder;

importandroid.view.SurfaceView;

importandroid.view.View;

importandroid.widget.ImageView;

importandroid.widget.TextView;

  

importjava.io.File;

importjava.io.FileNotFoundException;

importjava.io.FileOutputStream;

importjava.io.IOException;

  

publicclassMainActivityextendsAppCompatActivityimplementsSurfaceHolder.Callback,

    View.OnClickListener, Camera.PictureCallback {

  privateSurfaceView mSurfaceView;

  privateImageView mIvStart;

  privateTextView mTvCountDown;

  

  privateSurfaceHolder mHolder;

  

  privateCamera mCamera;

  

  privateHandler mHandler =newHandler();

  

  privateintmCurrentTimer =10;

  

  privatebooleanmIsSurfaceCreated =false;

  privatebooleanmIsTimerRunning =false;

  

  privatestaticfinalintCAMERA_ID =0;//后置摄像头

//  private static final int CAMERA_ID = 1; //前置摄像头

  privatestaticfinalString TAG = MainActivity.class.getSimpleName();

  

  @Override

  protectedvoidonCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

  

    initView();

    initEvent();

  }

  

  @Override

  protectedvoidonPause() {

    super.onPause();

  

    stopPreview();

  }

  

  privatevoidinitView() {

    mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);

    mIvStart = (ImageView) findViewById(R.id.start);

    mTvCountDown = (TextView) findViewById(R.id.count_down);

  }

  

  privatevoidinitEvent() {

    mHolder = mSurfaceView.getHolder();

    mHolder.addCallback(this);

  

    mIvStart.setOnClickListener(this);

  }

  

  @Override

  publicvoidsurfaceCreated(SurfaceHolder holder) {

    mIsSurfaceCreated =true;

  }

  

  @Override

  publicvoidsurfaceChanged(SurfaceHolder holder,intformat,intwidth,intheight) {

    startPreview();

  }

  

  @Override

  publicvoidsurfaceDestroyed(SurfaceHolder holder) {

    mIsSurfaceCreated =false;

  }

  

  privatevoidstartPreview() {

    if(mCamera !=null|| !mIsSurfaceCreated) {

      Log.d(TAG,"startPreview will return");

      return;

    }

  

    mCamera = Camera.open(CAMERA_ID);

  

    Camera.Parameters parameters = mCamera.getParameters();

    intwidth = getResources().getDisplayMetrics().widthPixels;

    intheight = getResources().getDisplayMetrics().heightPixels;

    Camera.Size size = getBestPreviewSize(width, height, parameters);

    if(size !=null) {

      //设置预览分辨率

      parameters.setPreviewSize(size.width, size.height);

      //设置保存图片的大小

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

    }

  

    //自动对焦

    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

    parameters.setPreviewFrameRate(20);

  

    //设置相机预览方向

    mCamera.setDisplayOrientation(90);

  

    mCamera.setParameters(parameters);

  

    try{

      mCamera.setPreviewDisplay(mHolder);

    }catch(Exception e) {

      Log.d(TAG, e.getMessage());

    }

  

    mCamera.startPreview();

  }

  

  privatevoidstopPreview() {

    //释放Camera对象

    if(mCamera !=null) {

      try{

        mCamera.setPreviewDisplay(null);

        mCamera.stopPreview();

        mCamera.release();

        mCamera =null;

      }catch(Exception e) {

        Log.e(TAG, e.getMessage());

      }

    }

  }

  

  privateCamera.Size getBestPreviewSize(intwidth,intheight,

                      Camera.Parameters parameters) {

    Camera.Size result =null;

  

    for(Camera.Size size : parameters.getSupportedPreviewSizes()) {

      if(size.width <= width && size.height <= height) {

        if(result ==null) {

          result = size;

        }else{

          intresultArea = result.width * result.height;

          intnewArea = size.width * size.height;

  

          if(newArea > resultArea) {

            result = size;

          }

        }

      }

    }

  

    returnresult;

  }

  

  @Override

  publicvoidonClick(View v) {

    switch(v.getId()) {

      caseR.id.start:

        if(!mIsTimerRunning) {

          mIsTimerRunning =true;

          mHandler.post(timerRunnable);

        }

        break;

    }

  }

  

  privateRunnable timerRunnable =newRunnable() {

    @Override

    publicvoidrun() {

      if(mCurrentTimer >0) {

        mTvCountDown.setText(mCurrentTimer +"");

  

        mCurrentTimer--;

        mHandler.postDelayed(timerRunnable,1000);

      }else{

        mTvCountDown.setText("");

  

        mCamera.takePicture(null,null,null, MainActivity.this);

        playSound();

  

        mIsTimerRunning =false;

        mCurrentTimer =10;

      }

    }

  };

  

  @Override

  publicvoidonPictureTaken(byte[] data, Camera camera) {

    try{

      FileOutputStream fos =newFileOutputStream(newFile

          (Environment.getExternalStorageDirectory() + File.separator +

              System.currentTimeMillis() +".png"));

  

      //旋转角度,保证保存的图片方向是对的

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

      Matrix matrix =newMatrix();

      matrix.setRotate(90);

      bitmap = Bitmap.createBitmap(bitmap,0,0,

          bitmap.getWidth(), bitmap.getHeight(), matrix,true);

      bitmap.compress(Bitmap.CompressFormat.PNG,100, fos);

      fos.flush();

      fos.close();

    }catch(FileNotFoundException e) {

      e.printStackTrace();

    }catch(IOException e) {

      e.printStackTrace();

    }

  

    mCamera.startPreview();

  }

  

  /**

   *  播放系统拍照声音

   */

  publicvoidplaySound() {

    MediaPlayer mediaPlayer =null;

    AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

    intvolume = audioManager.getStreamVolume( AudioManager.STREAM_NOTIFICATION);

  

    if(volume !=0) {

      if(mediaPlayer ==null)

        mediaPlayer = MediaPlayer.create(this, 

            Uri.parse("file:///system/media/audio/ui/camera_click.ogg"));

      if(mediaPlayer !=null) {

        mediaPlayer.start();

      }

    }

  }

}

 

有两点需要注意:对于Camera来说,默认是横屏的,所以预览的时候和图片保存的时候都是横屏的,需要调整角度。

设置相机预览方法:

 

 代码如下复制代码

//设置相机预览方向

mCamera.setDisplayOrientation(90);

 

保存图片的时候调整角度:

效果图如下:

热门栏目