欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-12-22 17:20:22
这篇博客为大家介绍android自定义相机,并且实现倒计时拍照功能。 首先自定义拍照会用到surfaceview控件显示照片的预览区域,以下是布局文件: act...

这篇博客为大家介绍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自定义相机实现定时拍照功能

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

上一篇:

下一篇: