Android 开发随手笔记之使用摄像头拍照
在android中,使用摄像头拍照一般有两种方法, 一种是调用系统自带的camera,另一种是自己写一个摄像的界面。
我们要添加如下权限:
<uses-permission android:name="android.permission.write_external_storage"/> <uses-permission android:name="android.permission.camera"/>
1、调用系统camera
调用系统自带的camera主要的步骤为:
(1)构造图片存储的路径名
(2)使用intent启动camera activity
(3)将拍摄的图片写入到文件
(4)将图片显示在mainactivity中
首先,构造图片名:
file filepath = new file(environment.getexternalstoragedirectory(), "mycamera"); if(!filepath.exists()){ filepath.mkdirs(); } filename = new file(filepath, system.currenttimemillis() + ".jpg"); try{ if(!filename.exists()){ filename.createnewfile(); } }catch (exception e){ e.printstacktrace(); }
然后,启动camera activity:
// intent用来启动系统自带的camera intent intent = new intent(mediastore.action_image_capture); // 将系统camera的拍摄结果写入到文件 intent.putextra(mediastore.extra_output, uri.fromfile(filename)); // 启动intent对应的activity,返回默认消息 startactivityforresult(intent, activity.default_keys_dialer);
最后,将图片显示在mainactivity内。这时,我们通过重载onactivityresult()方法来获取camera返回的消息。
@override protected void onactivityresult(int requestcode, int resultcode, intent data){ if(requestcode == activity.default_keys_dialer){ // mainactivity接收camera返回的消息,然后将已经写入的图片显示在imageview内 imageview.setimageuri(uri.fromfile(filename)); } }
完整代码为:
import android.app.activity; import android.content.intent; import android.net.uri; import android.os.bundle; import android.os.environment; import android.provider.mediastore; import android.util.log; import android.view.view; import android.widget.button; import android.widget.imageview; import java.io.file; public class mainactivity extends activity { private file filename = null; private button button; private imageview imageview; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); button = (button)findviewbyid(r.id.button); imageview = (imageview)findviewbyid(r.id.imageview); button.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { file filepath = new file(environment.getexternalstoragedirectory(), "mycamera"); if(!filepath.exists()){ filepath.mkdirs(); } filename = new file(filepath, system.currenttimemillis() + ".jpg"); try{ if(!filename.exists()){ filename.createnewfile(); } }catch (exception e){ e.printstacktrace(); } // intent用来启动系统自带的camera intent intent = new intent(mediastore.action_image_capture); // 将系统camera的拍摄结果写入到文件 intent.putextra(mediastore.extra_output, uri.fromfile(filename)); // 启动intent对应的activity,返回默认消息 startactivityforresult(intent, activity.default_keys_dialer); } }); } @override protected void onactivityresult(int requestcode, int resultcode, intent data){ if(requestcode == activity.default_keys_dialer){ // mainactivity接收camera返回的消息,然后将已经写入的图片显示在imageview内 imageview.setimageuri(uri.fromfile(filename)); } } }
2、自己写一个摄像界面
自己写摄像的界面,主要应用了surfaceview来显示摄像机的画面。然后通过一个button来保存当前的画面。
同样的,我们需要添加camera和sdcard权限:
<uses-permission android:name="android.permission.write_external_storage"/> <uses-permission android:name="android.permission.camera"/>
首先,我们初始化这个surfaceview,为这个surfaceview添加一个对应的callback即可:
private surfaceview surfaceview; private surfaceholder.callback callback; surfaceview = (surfaceview)findviewbyid(r.id.surfaceview); callback = new surfaceholder.callback(){ @override public void surfacecreated(surfaceholder holder) { startcamera(); // 用于启动摄像头 } @override public void surfacechanged(surfaceholder holder, int format, int width, int height) { } @override public void surfacedestroyed(surfaceholder holder) { stopcamera(); // 用于关闭摄像头 } }; surfaceview.getholder().addcallback(callback); // 将callback绑定到surfaceview
在启动摄像头的时候,首先打开摄像头连接,然后将其图像输出到surfaceview上,然后启动摄像头预览即可在surfaceview上显示摄像头的画面,这里的画面和实际画面相差有90度,所以我们需要将图像旋转90度之后才可以和拍摄的物体方向一致。
在关闭摄像头时,只要停止预览,然后释放摄像头资源即可。
public void startcamera(){ camera = camera.open(); try { camera.setpreviewdisplay(surfaceview.getholder()); camera.setdisplayorientation(90); camera.startpreview(); } catch (ioexception e) { e.printstacktrace(); } } public void stopcamera(){ camera.stoppreview(); camera.release(); camera = null; }
最后,是将拍摄到的图片保存到sdcard,我们单击button来拍摄图片,调用camera.takepicture()方法,其原型为:
/** * equivalent to takepicture(shutter, raw, null, jpeg). * * @see #takepicture(shuttercallback, picturecallback, picturecallback, picturecallback) */ public final void takepicture(shuttercallback shutter, picturecallback raw, picturecallback jpeg) { takepicture(shutter, raw, null, jpeg); }
其中,shutter为按快门瞬间的回调,就是说按快门瞬间会调用shuttercallback.onshutter()方法。raw是未压缩的图像的回调,即处理图像原始数据的时候会调用picturecallback.onpicturetaken()方法。jpeg为处理jpeg图片时候的回调,即我们需要将图像数据按照jpg格式保存的时候会调用这个方法,picturecallback.onpicturetaken()。这里我们就调用了这个方法,从而将jpg图片存储到sdcard上。
button.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { camera.takepicture(null, null, new camera.picturecallback() { @override public void onpicturetaken(byte[] data, camera camera) { try { file filepath = new file(environment.getexternalstoragedirectory(), "mycamera"); if(!filepath.exists()) { filepath.mkdirs(); } file filename = new file(filepath, system.currenttimemillis() + ".jpg"); filename.createnewfile(); fileoutputstream fos = new fileoutputstream(filename); fos.write(data); fos.flush(); fos.close(); } catch (ioexception e) { e.printstacktrace(); } } }); } });
这样,我们便实现了用surfaceview预览摄像头画面,点击button将当前预览保存到sdcard中。
完整代码如下:
import android.app.activity; import android.hardware.camera; import android.os.bundle; import android.os.environment; import android.view.surfaceholder; import android.view.surfaceview; import android.view.view; import android.widget.button; import java.io.file; import java.io.fileoutputstream; import java.io.ioexception; public class mainactivity extends activity { private camera camera; private button button; private surfaceview surfaceview; private surfaceholder.callback callback; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); button = (button)findviewbyid(r.id.button); surfaceview = (surfaceview)findviewbyid(r.id.surfaceview); callback = new surfaceholder.callback(){ @override public void surfacecreated(surfaceholder holder) { startcamera(); } @override public void surfacechanged(surfaceholder holder, int format, int width, int height) { } @override public void surfacedestroyed(surfaceholder holder) { stopcamera(); } }; surfaceview.getholder().addcallback(callback); button.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { camera.takepicture(null, null, new camera.picturecallback() { @override public void onpicturetaken(byte[] data, camera camera) { try { file filepath = new file(environment.getexternalstoragedirectory(), "mycamera"); if(!filepath.exists()) { filepath.mkdirs(); } file filename = new file(filepath, system.currenttimemillis() + ".jpg"); filename.createnewfile(); fileoutputstream fos = new fileoutputstream(filename); fos.write(data); fos.flush(); fos.close(); } catch (ioexception e) { e.printstacktrace(); } } }); } }); } public void startcamera(){ camera = camera.open(); try { camera.setpreviewdisplay(surfaceview.getholder()); camera.setdisplayorientation(90); camera.startpreview(); } catch (ioexception e) { e.printstacktrace(); } } public void stopcamera(){ camera.stoppreview(); camera.release(); camera = null; } }
以上所述是本文给大家介绍的关于android 开发随手笔记之使用摄像头拍照的全部内容,希望大家喜欢。
推荐阅读
-
Android 开发随手笔记之使用摄像头拍照
-
android开发之调用手机的摄像头使用MediaRecorder录像并播放
-
Android 开发随手笔记之使用摄像头拍照
-
Android开发笔记之:Dialog的使用详解
-
Android开发笔记之:一分钟学会使用Logcat调试程序的详解
-
android开发之调用手机的摄像头使用MediaRecorder录像并播放
-
Android开发笔记之:Dialog的使用详解
-
Android开发笔记之:一分钟学会使用Logcat调试程序的详解
-
Android开发笔记之 RecyclerView和ScrollView嵌套使用,ListView和ScrollView嵌套使用对比
-
Android开发笔记之 RecyclerView和ScrollView嵌套使用,ListView和ScrollView嵌套使用对比