首页 > 系统 > Android > 正文

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

2019-12-12 03:56:26
字体:
来源:转载
供稿:网友

这篇博客为大家介绍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);

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

效果图如下:


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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表