Android 사용자 정의 카메라 정시 촬영 기능 구현

이 블 로 그 는 안 드 로 이 드 사용자 정의 카 메 라 를 소개 하고 카운트다운 사진 기능 을 실현 한다.
먼저 사용자 정의 사진 은 Surface View 컨트롤 로 사진 의 미리 보기 영역 을 표시 합 니 다.다음은 레이아웃 파일 입 니 다.
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);
그림 저장 시 각도 조절:

효과 도 는 다음 과 같다.

이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기