Android开发之控制摄像头拍照
如今的手机一般都会提供相机功能,有些相机的镜头甚至支持1300万以上像素,有些甚至支持独立对焦、光学变焦这些仅仅有单反才有的功能,甚至有些手机直接宣传能够拍到星星。能够说手机已经变成了专业数码相机。为了充分利用手机上的相机功能, Android系统提供了Camera类来控制相机拍照。如今就让我们看一下假设使用Camera类来控制手机拍照。
使用Camera控制手机拍照的过程例如以下:
1) 调用Camera的open()方法打开相机。该方法默认打开后置摄像头。
假设须要打开指定摄像头,能够为该方法传入摄像头ID。
2) 调用Camera的getParameters()方法获取拍照參数。该方法返回一个 Camera.Parameters 对象。
3) 调用Camera.Parameters对象方法设置拍照參数。
4) 调用Camera的startPreview()方法開始预览取景。在预览取景之前须要调用Camera 的 setPreviewDisplay(SurfaceHolder holder)方法设置使用哪个Surface View 来显示取景照片。
5) 调用Camera的takePicture()方法进行拍照。
6) 结束程序时,调用Camera的stopPreview()结束取景预览,并调用release()方法释放资源。
应用实例:拍照时自己主动对焦
以下的实例示范了使用Camera来进行拍照、当用户按下拍照键时,该应用会自己主动对焦,当对焦成功时拍下照片。该程序的界面中仅仅提供了一个SurfaceView来显示预览取景。十分简单。该程序代码例如以下:
- package com.jph.camera;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Locale;
- import android.app.Activity;
- import android.graphics.Bitmap;
- import android.graphics.Bitmap.CompressFormat;
- import android.graphics.BitmapFactory;
- import android.graphics.ImageFormat;
- import android.hardware.Camera;
- import android.hardware.Camera.AutoFocusCallback;
- import android.hardware.Camera.PictureCallback;
- import android.hardware.Camera.ShutterCallback;
- import android.os.Bundle;
- import android.os.Environment;
- import android.util.DisplayMetrics;
- import android.view.Display;
- import android.view.SurfaceHolder;
- import android.view.SurfaceHolder.Callback;
- import android.view.SurfaceView;
- import android.view.View;
- import android.view.Window;
- import android.view.WindowManager;
- import android.widget.EditText;
- import android.widget.ImageView;
- import android.widget.Toast;
- /**
- * 控制手机拍照
- * @author jph
- * Date:2014.08.20
- * */
- public class CaptureImage extends Activity
- {
- SurfaceView sView;
- SurfaceHolder surfaceHolder;
- int screenWidth, screenHeight;
- // 定义系统所用的照相机
- Camera camera;
- // 是否在预览中
- boolean isPreview = false;
- @Override
- public 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.main);
- // 获取窗体管理器
- WindowManager wm = getWindowManager();
- Display display = wm.getDefaultDisplay();
- DisplayMetrics metrics = new DisplayMetrics();
- // 获取屏幕的宽和高
- display.getMetrics(metrics);
- screenWidth = metrics.widthPixels;
- screenHeight = metrics.heightPixels;
- // 获取界面中SurfaceView组件
- sView = (SurfaceView) findViewById(R.id.sView);
- // 获得SurfaceView的SurfaceHolder
- surfaceHolder = sView.getHolder();
- // 为surfaceHolder加入一个回调监听器
- surfaceHolder.addCallback(new Callback()
- {
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format,
- int width, int height)
- {
- }
- @Override
- public void surfaceCreated(SurfaceHolder holder)
- {
- // 打开摄像头
- initCamera();
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder holder)
- {
- // 假设camera不为null ,释放摄像头
- if (camera != null)
- {
- if (isPreview) camera.stopPreview();
- camera.release();
- camera = null;
- }
- }
- });
- }
- private void initCamera()
- {
- if (!isPreview)
- {
- // 此处默认打开后置摄像头。
- // 通过传入參数能够打开前置摄像头
- camera = Camera.open(0); //①
- camera.setDisplayOrientation(90);
- }
- if (camera != null && !isPreview)
- {
- try
- {
- Camera.Parameters parameters = camera.getParameters();
- // 设置预览照片的大小
- parameters.setPreviewSize(screenWidth, screenHeight);
- // 设置预览照片时每秒显示多少帧的最小值和最大值
- parameters.setPreviewFpsRange(4, 10);
- // 设置图片格式
- parameters.setPictureFormat(ImageFormat.JPEG);
- // 设置JPG照片的质量
- parameters.set("jpeg-quality", 85);
- // 设置照片的大小
- parameters.setPictureSize(screenWidth, screenHeight);
- // 通过SurfaceView显示取景画面
- camera.setPreviewDisplay(surfaceHolder); //②
- // 開始预览
- camera.startPreview(); //③
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- isPreview = true;
- }
- }
- /**
- * 此方法在布局文件里调用
- * */
- public void capture(View source)
- {
- if (camera != null)
- {
- // 控制摄像头自己主动对焦后才拍照
- camera.autoFocus(autoFocusCallback); //④
- }
- }
- AutoFocusCallback autoFocusCallback = new AutoFocusCallback()
- {
- // 当自己主动对焦时激发该方法
- @Override
- public void onAutoFocus(boolean success, Camera camera)
- {
- if (success)
- {
- // takePicture()方法须要传入3个监听器參数
- // 第1个监听器:当用户按下快门时激发该监听器
- // 第2个监听器:当相机获取原始照片时激发该监听器
- // 第3个监听器:当相机获取JPG照片时激发该监听器
- camera.takePicture(new ShutterCallback()
- {
- public void onShutter()
- {
- // 按下快门瞬间会运行此处代码
- }
- }, new PictureCallback()
- {
- public void onPictureTaken(byte[] data, Camera c)
- {
- // 此处代码能够决定是否须要保存原始照片信息
- }
- }, myJpegCallback); //⑤
- }
- }
- };
- PictureCallback myJpegCallback = new PictureCallback()
- {
- @Override
- public void onPictureTaken(byte[] data, Camera camera)
- {
- // 依据拍照所得的数据创建位图
- final Bitmap bm = BitmapFactory.decodeByteArray(data, 0,
- data.length);
- String fileName=getFileNmae();
- if (fileName==null) return;
- // 创建一个位于SD卡上的文件
- File file = new File(fileName);
- FileOutputStream outStream = null;
- try
- {
- // 打开指定文件相应的输出流
- outStream = new FileOutputStream(file);
- // 把位图输出到指定文件里
- bm.compress(CompressFormat.JPEG, 100,
- outStream);
- outStream.close();
- Toast.makeText(CaptureImage.this, "照片以保存到"+fileName,
- Toast.LENGTH_SHORT).show();
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- // 又一次浏览
- camera.stopPreview();
- camera.startPreview();
- isPreview = true;
- }
- };
- /**
- * 返回摄取照片的文件名称
- * @return 文件名称
- * */
- protected String getFileNmae() {
- // TODO Auto-generated method stub
- String fileName;
- if (!Environment.getExternalStorageState().equals
- (Environment.MEDIA_MOUNTED)) {
- Toast.makeText(this, "监測到你的手机没有插入SD卡,请插入SD卡后再试",
- Toast.LENGTH_LONG).show();
- return null;
- }
- SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH.mm.ss", Locale.getDefault());
- fileName=Environment.getExternalStorageDirectory()+File.separator
- +sdf.format(new Date())+".JPG";
- return fileName;
- }
- }
程序执行效果图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ3l1emhlbmdmYW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="控制摄像头拍照">
Android开发之控制摄像头拍照的更多相关文章
- 在WPF中使用AForge.net控制摄像头拍照
原文:在WPF中使用AForge.net控制摄像头拍照 利用AForge.net控制摄像头拍照最方便的方法就是利用PictureBox显示摄像头画面,但在WPF中不能直接使用PictureBox.必须 ...
- Android 开发 Camera类的拍照与录像
前言 在开发Android应用的时候,如果需要调用摄像头拍照或者录像,除了通过Intent调用系统现有相机应用进行拍照录像之外,还可以通过直接调用Camera硬件去去获取摄像头进行拍照录像的操作.本篇 ...
- VS2010开发MFC ActiveX,摄像头拍照上传Webservice(2)
继续记录,第二步开发摄像头拍照功能. 使用vfw.h开发摄像头拍照功能,关于vfw网上有很多文章,很多代码可以参考 参考:http://blog.163.com/huangqiao_8/blog/st ...
- VS2010开发MFC ActiveX,摄像头拍照上传Webservice(1)
最近工作项目,BS中需要用到摄像头拍照,需要存储本地,同时上传到服务器,尝试使用vc++做ActiveX来实现. 完全没有使用过vc,上网搜索各种知识,初步完成.在这里记录下有帮助的资料. 第一步:编 ...
- 用Python控制摄像头拍照并发邮件
概述前言 工具 思路 安装及导入包 设置参数 实现拍照 构造邮件内容 发送邮件 判断网络连接 开机自启 后记 o1 前言为什么会有写这个程序的想法呢? 最初的想法是写一个可以用电脑前置摄像头拍照的程序 ...
- Android多媒体应用开发-控制摄像头拍照
现在的手机的功能可谓是五花八门,手机照相功能就是特别突出的一点,现在的手机照相机甚至成了专业数码照相机,可以拍摄出清晰的照片和录制高分辨率的视频.Android操作系统呢,提供了相应的功能来控制拍照: ...
- Android开发之控制Toast的开启与关闭
开发这个程序之前先解释一下,为什么Toast信息提示框在显示一定时间后会自己主动消失?由于在Android系统中有一个Toast队列,系统会依次从这个队列中取出一个Toast,并显示它.在显示了指定时 ...
- Android开发:实时处理摄像头预览帧视频------浅析PreviewCallback,onPreviewFrame,AsyncTask的综合应用(转)
原文地址:http://blog.csdn.net/yanzi1225627/article/details/8605061# 很多时候,android摄像头模块不仅预览,拍照这么简单,而是需要在预览 ...
- Android开发_控制硬加速hardwareAccelerated
控制硬加速 hardwareAccelerated也是一种优化的手段 从Android3.0 (API level11)开始,Android的2D显示管道被被设计得更加支持硬加速了.硬加速使用GPU承 ...
随机推荐
- C#.NET常见问题(FAQ)-如何把资源嵌入到项目中
首先把图像的资源添加到项目中, 选择资源文件(常规),修改一下这个资源的名字(比如叫做ButtonPic) 我们假定已经把图像放到了项目的某个文件夹下(比如Pic文件夹下,注意不是bin目录下 ...
- 如何使用FLASHGOT下载网页FLASH
1 注意火狐的广告屏蔽插件可能将一些有用的东西屏蔽掉,从而无法得到广告FLASH, 2 随后即可在桌面上找到所需文件 你也可以按住A/T并单击FLASH文件(不论鼠标是否被替换为其他图形)迅雷会自动探 ...
- Mockito: InvalidUseOfMatchersException
异常报错信息: org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Invalid use of argument match ...
- iOS强引用和弱引用
保留一个对象创建了一个对该对象的“强”引用.一个对象只有在它的所有强引用都被释放后才能被回收.因此,一个对象的生命周期取决于其强引用的所有者.在某些情况下,这种行为可能并不理想.您可能想要引用一个对象 ...
- 玩转oracle学习第五天
1.上节回想 2.维护数据的完整性 3.管理索引 4.管理权限和角色 1.掌握维护oracle数据完整性的技巧 2.理解索引的概念,会建立索引 3.管理oracle的权限和角色 介绍:维 ...
- Flask 源代码阅读笔记
我认为我已经养成了一个坏习惯.在使用一个框架过程中对它的内部原理非常感兴趣,有时候须要花不少精力才 明确,这也导致了学习的缓慢,但换来的是对框架的内部机理的熟悉,正如侯捷所说,源代码面前,了无秘密.这 ...
- 原创Oracle数据泵导出/导入(expdp/impdp)
//创建目录 create Or Replace directory dpdata1 as 'd:\test\dump'; //赋予读写权限 grant read,write on directory ...
- posix_memalign详细解释(转)——自定义对齐大小的内存分配函数
转载:http://hi.baidu.com/freelonely/blog/item/340341077c4d287302088189.html 预对齐内存的分配 在大多数情况下,编译器和C库透明地 ...
- 赵雅智:service_bindService生命周期
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhb3lhemhpMjEyOQ==/font/5a6L5L2T/fontsize/400/fill/I0 ...
- cocos2d-x项目101次相遇-安装和环境搭建 -xcode
cocos2d-x 101次相遇 / 文件夹 1 安装和环境搭建 -xcode 2 Scenes . Director, Layers, Sprites 3 建立图片菜单 4 在 ...