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);
保存图片的时候调整角度:
效果图如下:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。