Android相机应用
2015-11-28 20:39
267 查看
Android相机应用
布局
功能实现
拍照
附录
1. 这里我们先设置放置Button父元素RelativeLayout的
我们必须要为RelativeLayout设置一个ID,方面我们在之后触摸事件后修改其属性。
2. 在RelativeLayout中设置Button的属性,主要是设置位置和onClick事件。
至此,布局基本完成。
1. 根据之前说的操作逻辑,我们首先实现触摸屏幕显示拍照按钮。
重写
2. 把摄像头采集的画面输出到屏幕上。
编码之前千万不要忘记添加相机使用权限,之后估计还会用到SD卡读写的权限,这里也一并加上:
现在我们开始实现
在
至此,完成了应用实现打开camera把采集的视频流回显到屏幕上的功能。
快门事件的回调
获取原始数据的回调
获取编码后数据的回调
这里我们想要在SD卡中存储*.jpg文件,所以前两项给null,对于第三项,我们编写内部类实现PictureCallback接口并完成未实现的方法:
布局
功能实现
拍照
附录
Android相机应用
Android应用可以调用系统相机和相册模块,学会使用相机会在特定的应用中有帮助,比如我最近的项目中用到二维码扫描就跟这个有关。布局
这里用到的一个关键性的布局控件叫做<Surface View> <Surface View />现在我们要求达到的效果是,将camera采集到输出到SurfaceView控件上,当我们触摸屏幕的时候,将显示拍照Button。
1. 这里我们先设置放置Button父元素RelativeLayout的
android:visibility属性为gone
[code]<RelativeLayout android:id="@+id/buttonLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:visibility="gone" >
我们必须要为RelativeLayout设置一个ID,方面我们在之后触摸事件后修改其属性。
2. 在RelativeLayout中设置Button的属性,主要是设置位置和onClick事件。
[code] <Button android:id="@+id/btnTakePic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:gravity="center" android:onClick="TakePicture" android:text="@string/btnTakePic" />
至此,布局基本完成。
功能实现
在实现功能之前,我们希望打开相机之后,相机采集的数据回显到屏幕能够全屏显示,也就意味着没有屏幕最上方的TITLE显示。这样,需要我们在
onCreate()方法中,加载布局文件之前先干掉title,并且全屏显示。
[code]// 显示界面之前修改窗口属性 requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
1. 根据之前说的操作逻辑,我们首先实现触摸屏幕显示拍照按钮。
重写
onTouchEvent()方法,在方法中,我们通过对实例化过的私有成员变量
layout的设置,来显示布局中的RelativeLayout(button就位于这个相对布局中)
[code]@Override public boolean onTouchEvent(MotionEvent event) { if(event.getAction()==MotionEvent.ACTION_DOWN){ layout.setVisibility(ViewGroup.VISIBLE);//0x00000000 return true; } return super.onTouchEvent(event); }
2. 把摄像头采集的画面输出到屏幕上。
编码之前千万不要忘记添加相机使用权限,之后估计还会用到SD卡读写的权限,这里也一并加上:
[code]<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
现在我们开始实现
采集->显示这部分代码。首先通过找到SurfaceView控件并实例化,通过
getHolder()方法来配置:
[code]surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); surfaceView.getHolder().setFixedSize(176, 144); surfaceView.getHolder().setKeepScreenOn(true); //设置回调函数,当SurfaceView被创建的时候调用。 surfaceView.getHolder().addCallback(new SurfaceCallback());
在
addCallback()方法中需要一个对象,这里创建内部类实现Callback接口,完成未实现的方法:
[code] private final class SurfaceCallback implements Callback{ @Override public void surfaceCreated(SurfaceHolder holder) { try{ camera=Camera.open();//打开摄像头 /*也可以使用默认参数 Camera.Parameters parameters=camera.getParameters(); parameters.setPreviewSize(1920,1080); parameters.setPreviewFrameRate(15); parameters.setPictureSize(1024, 768); parameters.setJpegQuality(100); camera.setParameters(parameters); */ //采集的图像回显是斜的,在StackOverFlow上面看到的方法修正,但是好像并没有什么暖用 Camera.Parameters params = camera.getParameters(); //params.set("orientation", "portrait"); //params.set("rotation",270); //下述才是正解 camera.setDisplayOrientation(90);//旋转90度 camera.setParameters(params); camera.setPreviewDisplay(holder);//采集->SurfaceView camera.startPreview();//开始预览 }catch (Exception e){ e.printStackTrace(); } //Log.i("zhangxiao",parameters.flatten()); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { if(camera!=null){ //销毁camera camera.release(); camera=null; } } }
至此,完成了应用实现打开camera把采集的视频流回显到屏幕上的功能。
拍照
拍照功能的实现就简单多了,我们设置Button的onClick事件,当点击按钮时完成拍照,并将快照保存到SD卡的根目录中。事实上,我们使用camera.takePicture()即可完成拍照,这里面需要我们给定3个回调对象,分别是:
快门事件的回调
获取原始数据的回调
获取编码后数据的回调
这里我们想要在SD卡中存储*.jpg文件,所以前两项给null,对于第三项,我们编写内部类实现PictureCallback接口并完成未实现的方法:
[code]private final class JpegCallback implements PictureCallback{ /* 拍照回调 * @see android.hardware.Camera.PictureCallback#onPictureTaken(byte[], android.hardware.Camera) */ @Override public void onPictureTaken(byte[] data, Camera camera) { //打开文件 File jpgFile = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg"); try { //创建文件输出流 FileOutputStream outStream =new FileOutputStream(jpgFile); //写文件 outStream.write(data); outStream.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
附录
com.example.takepicture.MainActivity.java[code]public class MainActivity extends Activity { private View layout; private Camera camera; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 显示界面之前修改窗口属性 requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_main); layout=(View)this.findViewById(R.id.buttonLayout); SurfaceView surfaceView=(SurfaceView)this.findViewById(R.id.surfaceView); surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); surfaceView.getHolder().setFixedSize(176, 144); surfaceView.getHolder().setKeepScreenOn(true); surfaceView.getHolder().addCallback(new SurfaceCallback()); } //TakePicture public void TakePicture(View v){ if(camera!=null){ //快门回调, 原始数据, 压缩数据 camera.takePicture(null, null, new JpegCallback()); } } private final class JpegCallback implements PictureCallback{ /* 拍照回调 * @see android.hardware.Camera.PictureCallback#onPictureTaken(byte[], android.hardware.Camera) */ @Override public void onPictureTaken(byte[] data, Camera camera) { File jpgFile = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg"); try { FileOutputStream outStream =new FileOutputStream(jpgFile); outStream.write(data); outStream.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private final class SurfaceCallback implements Callback{ @Override public void surfaceCreated(SurfaceHolder holder) { try{ camera=Camera.open();//打开摄像头 /* Camera.Parameters parameters=camera.getParameters(); parameters.setPreviewSize(1920,1080); parameters.setPreviewFrameRate(15); parameters.setPictureSize(1024, 768); parameters.setJpegQuality(100); camera.setParameters(parameters); */ Camera.Parameters params = camera.getParameters(); //params.set("orientation", "portrait"); //params.set("rotation",270); camera.setDisplayOrientation(90);//旋转90度 camera.setParameters(params); camera.setPreviewDisplay(holder); camera.startPreview(); }catch (Exception e){ e.printStackTrace(); } //Log.i("zhangxiao",parameters.flatten()); //捕获的预览画面的大小 } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { if(camera!=null){ camera.release(); camera=null; } } } @Override public boolean onTouchEvent(MotionEvent event) { if(event.getAction()==MotionEvent.ACTION_DOWN){ layout.setVisibility(ViewGroup.VISIBLE);//0x00000000 return true; } return super.onTouchEvent(event); } }
相关文章推荐
- Android Studio 怎么查看方法注释
- android:clipChildren妙用:底部的radioGroup中间的button突出
- android115 自定义控件
- [转]用android LinearLayout和RelativeLayout实现精确布局
- android动画
- Android调用系统相机方法及保存照片方式
- Android中listView中用于下载、显示图片
- android的IPC机制
- 手机点击QQ直接跳转
- Android地图开发 安全码生成
- Android Calendar的学习与运用
- 让android定时关机的实现方法
- android Gson的使用
- 再谈ArcGIS Runtime SDK for Android中文标注无法显示的问题
- Android之RxJava(一)
- android-Creating a Content Provider(2)
- Android知识总结:Universal-Imageloader学习笔记1 基本功能与配置
- Android系统源码下载过程
- android中用Spannable在TextView中设置超链接、颜色、字体
- Android环境的搭建