当前位置: 移动技术网 > 移动技术>移动开发>Android > Android自定义相机实现定时拍照功能

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

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

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

效果图如下:


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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网