Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android自定義相機實現定時拍照功能

Android自定義相機實現定時拍照功能

編輯:關於Android編程

這篇博客為大家介紹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);

保存圖片的時候調整角度:

效果圖如下:


以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved