首页 > 系统 > Android > 正文

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

2019-10-23 19:51:28
字体:
来源:转载
供稿:网友

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

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"   android:layout_width="match_parent"   android:layout_height="match_parent" >    <SurfaceView     android:id="@+id/surface_view"     android:layout_width="match_parent"     android:layout_height="match_parent" />    <RelativeLayout     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical" >      <ImageView       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"/>      <TextView       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"/>   </RelativeLayout> </FrameLayout> 

MainActivity.java

package com.jackie.timercamera;  import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.hardware.Camera; import android.media.AudioManager; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.widget.ImageView; import android.widget.TextView;  import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;  public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback,     View.OnClickListener, Camera.PictureCallback {   private SurfaceView mSurfaceView;   private ImageView mIvStart;   private TextView mTvCountDown;    private SurfaceHolder mHolder;    private Camera mCamera;    private Handler mHandler = new Handler();    private int mCurrentTimer = 10;    private boolean mIsSurfaceCreated = false;   private boolean mIsTimerRunning = false;    private static final int CAMERA_ID = 0; //后置摄像头 //  private static final int CAMERA_ID = 1; //前置摄像头   private static final String TAG = MainActivity.class.getSimpleName();    @Override   protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_main);      initView();     initEvent();   }    @Override   protected void onPause() {     super.onPause();      stopPreview();   }    private void initView() {     mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);     mIvStart = (ImageView) findViewById(R.id.start);     mTvCountDown = (TextView) findViewById(R.id.count_down);   }    private void initEvent() {     mHolder = mSurfaceView.getHolder();     mHolder.addCallback(this);      mIvStart.setOnClickListener(this);   }    @Override   public void surfaceCreated(SurfaceHolder holder) {     mIsSurfaceCreated = true;   }    @Override   public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {     startPreview();   }    @Override   public void surfaceDestroyed(SurfaceHolder holder) {     mIsSurfaceCreated = false;   }    private void startPreview() {     if (mCamera != null || !mIsSurfaceCreated) {       Log.d(TAG, "startPreview will return");       return;     }      mCamera = Camera.open(CAMERA_ID);      Camera.Parameters parameters = mCamera.getParameters();     int width = getResources().getDisplayMetrics().widthPixels;     int height = 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();   }    private void stopPreview() {     //释放Camera对象     if (mCamera != null) {       try {         mCamera.setPreviewDisplay(null);         mCamera.stopPreview();         mCamera.release();         mCamera = null;       } catch (Exception e) {         Log.e(TAG, e.getMessage());       }     }   }    private Camera.Size getBestPreviewSize(int width, int height,                       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 {           int resultArea = result.width * result.height;           int newArea = size.width * size.height;            if (newArea > resultArea) {             result = size;           }         }       }     }      return result;   }    @Override   public void onClick(View v) {     switch (v.getId()) {       case R.id.start:         if (!mIsTimerRunning) {           mIsTimerRunning = true;           mHandler.post(timerRunnable);         }         break;     }   }    private Runnable timerRunnable = new Runnable() {     @Override     public void run() {       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   public void onPictureTaken(byte[] data, Camera camera) {     try {       FileOutputStream fos = new FileOutputStream(new File           (Environment.getExternalStorageDirectory() + File.separator +               System.currentTimeMillis() + ".png"));        //旋转角度,保证保存的图片方向是对的       Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);       Matrix matrix = new Matrix();       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();   }    /**    *  播放系统拍照声音    */   public void playSound() {     MediaPlayer mediaPlayer = null;     AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);     int volume = 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);

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

Android相机定时拍照,Android自定义相机定时拍照,Android相机拍照

效果图如下:

Android相机定时拍照,Android自定义相机定时拍照,Android相机拍照

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VEVB武林网。


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表