相机android
2016-03-24 08:41:57 qian_xiao_lj 阅读数 1343
java.lang.Object
android.hardware.camera

类概述

相机类用于设置图像捕获设置,启动/停止预览、拍照、和检索视频帧的编码。这个类是一个为相机服务客户,管理实际相机硬件。

访问设备的相机,你必须申报相机在你的Android Manifest许可。当然也要包括<uses-feature>manifest元素声明应用程序所使用的相机功能。例如,如果您使用的相机和自动对焦功能,你的清单应包括以下内容:

<uses-permissionAndroid的:名称=“Android的许可。相机”/>
<uses-featureAndroid的:名称=“Android的硬件。相机”/>
<uses-featureAndroid的:名称=“Android的硬件。相机自动对焦”/>

拍照这一类,使用以下步骤:

  1. 从获取摄像机的一个实例打开(int)
  2. 把现有的(默认)设置getparameters()
  3. 如果有必要,修改回来相机参数对象并调用setparameters(相机参数)
  4. 如果需要,打电话setdisplayorientation(int)
  5. 重要通过一个完全初始化:SurfaceHolder.lockCanvassetpreviewdisplay(surfaceholder)。没有表面,相机将无法启动预览。
  6. 重要电话:startpreview()开始更新预览表。预览之前你必须拍一张照片开始。
  7. 想你的时候,电话(camera.shuttercallback TakePicture、拍照、产生图片时触发,拍照、产生图片时触发,相机。picturecallback)捕捉到的照片。等提供实际的图像数据的回调。
  8. 拍照后,预览显示将停止。拍些照片,电话startpreview()再来一次
  9. 呼叫stoppreview()停止更新预览表
  10. 重要:呼叫release()释放相机由其他应用程序使用。应用程序应该立即释放相机onpause()(再—open()它在onresume()

快速切换到录像模式,使用这些步骤:

  1. 获取并初始化一个摄像头和上述开始预览。
  2. 呼叫unlock()让媒体过程访问摄像机。
  3. 通过相机setcamera(相机)。看到mediarecorder视频记录信息
  4. 当录制完成,调用reconnect()重新获得和重新锁定相机。
  5. 如果需要,重新启动预览拍更多的照片或视频。
  6. 呼叫stoppreview()release()如上所述

这类不是线程安全的,并且是用一个事件的线程。最耗时的操作(预览,焦点,照片拍摄,等)并调用回调异步发生的必要。回调将在事件线程中调用打开(int)被称为从。这个类中的方法不能被多个线程同时。

谨慎:不同的Android设备可能有不同的硬件规格,如万像素的评级和自动对焦能力。为了能够与更多的设备兼容的应用程序,你不应该把关于设备的摄像头规格的假设。

开发者指南

关于使用相机的更多信息,阅读相机开发指南

概要



公共方法
最后的空隙 addcallbackbuffer(byte [] callbackbuffer)
增加了一个预分配的缓冲区来预览回调缓冲队列。
最后的空隙 自动对焦camera.autofocuscallbackCB)
启动相机自动对焦和注册一个回调函数运行时,相机聚焦。
最后的空隙 cancelautofocus()
取消任何自动对焦功能的进展。
最后布尔 enableshuttersound(布尔启用)

启用或禁用默认的快门声拍照的时候。

static void getcamerainfo(int cameraid,camera.camerainfocamerainfo)
返回有关特定相机的信息。
静态变量 getnumberofcameras()
返回物理相机可以在数本装置。
相机参数 得到相机的参数()
返回此相机服务的当前设置。
最后的空隙 锁具()
重新锁定相机防止其他进程访问它。
静态相机 开放(int cameraid)
创建一个新的相机对象访问特定硬件的相机。
静态相机 开放()
创建一个新的相机对象访问第一个背对着设备上的照相机。
最后的空隙 重新连接()
重新连接到相机服务后,另一个进程使用它。
最后的空隙 发布()
断开并释放相机的对象资源。
无效 setautofocusmovecallbackcamera.autofocusmovecallbackCB)
设置相机自动对焦移回调。
最后的空隙 setdisplayorientation(int度)
设置预览显示顺时针旋转度。
最后的空隙 seterrorcallbackcamera.errorcallbackCB)
注册一个回调函数被调用时发生错误。
最后的空隙 setfacedetectionlistenercamera.facedetectionlistener听众)
注册一个监听器被通知在预览框中检测到的面孔。
最后的空隙 setoneshotpreviewcallbackcamera.previewcallbackCB)

安装一个回调是为下一个预览除了显示在屏幕框架调用。

无效 setparameters相机参数参数)
更改此相机服务设置
最后的空隙 setpreviewcallbackcamera.previewcallbackCB)

安装一个回调是除了显示屏幕上的每个预览框架调用。

最后的空隙 setpreviewcallbackwithbuffercamera.previewcallbackCB)

安装一个回调是为每个预览框架调用,使用缓冲区提供addcallbackbuffer(byte []),除了显示在屏幕上

最后的空隙 setpreviewdisplaySurfaceHolder.lockCanvas持有人)
表面用于实时预览
最后的空隙 setpreviewtexture表面结构表面结构)
表面结构用于实时预览
最后的空隙 setzoomchangelistenercamera.onzoomchangelistener听众)
注册侦听器时要通知缩放值更新摄像头驱动在平滑缩放。
最后的空隙 startfacedetection()
从the Face detection。
最后的空隙 开始预览()
开始捕捉和绘制到屏幕预览框。
最后的空隙 startsmoothzoom(int值)
放大到要求值平稳
最后的空隙 stopfacedetection()
the Face检测停止。
最后的空隙 停止预览()
停止捕获和图纸预览框的表面,并将相机未来的呼叫startpreview()
最后的空隙 stopsmoothzoom()
停止平滑缩放
最后的空隙 TakePicturecamera.shuttercallback快门,拍照、产生图片时触发原,拍照、产生图片时触发JPEG)
相当于TakePicture(快门,原,null,JPEG)。
最后的空隙 TakePicturecamera.shuttercallback快门,拍照、产生图片时触发原,拍照、产生图片时触发postview,拍照、产生图片时触发JPEG)
触发器的异步图像捕捉。
最后的空隙 解锁()
打开相机允许另一个进程访问它。
     
保护的方法
无效 完成()
当调用垃圾收集器发现这个实例不可达。
[扩展]
继承的方法
从类java.lang.Object

常数


public static final字符串action_new_picture

广播操作:新图片是由相机拍摄,和图片的条目被添加到媒体商店。GetData()是URI的图片

常数值:“android.hardware.action.new _图片”

public static final字符串action_new_video

广播操作:一个新的视频被摄像机记录,和视频的入口已被添加到媒体商店。GetData()是URI的视频

常数值:“android.hardware.action.new _视频”

public static final intcamera_error_server_died

加入API级别1

媒体服务器死了。在这种情况下,应用程序必须释放相机对象实例化一个新的。

常数值:100(0x00000064)

public static final intcamera_error_unknown

加入API级别1

未指定摄像机误差

常数值:1(0x00000001)

公共方法


公众最后的空白addcallbackbuffer(byte [] callbackbuffer)

增加了一个预分配的缓冲区来预览回调缓冲队列。应用程序可以添加一个或多个缓冲区队列。当一个预览帧到达时,至少还有一个可用的缓冲区,缓冲区将用于从队列中移除。然后预览回调与缓冲区调用。如果一个帧到达时,没有缓冲的左边,帧将被丢弃。应用程序应加缓冲器回来当他们完成他们的数据处理。

格式除了YV12,缓冲区的大小乘以预览图像的宽度,确定的高度,和每像素的字节。宽度和高度可以读getpreviewsize()。每像素的字节可以计算getbitsperpixel(int)8、利用图像格式getpreviewformat()

如果使用YV12格式,大小可以用列方程计算setpreviewformat(int)

此方法时才有必要setpreviewcallbackwithbuffer(previewcallback)使用。什么 时候setpreviewcallback(previewcallback)setoneshotpreviewcallback(previewcallback)使用缓冲区自动分配。当提供的缓冲区太小,将预览帧数据,预览回调将返回null,缓冲区将从缓冲队列中移除。

参数
callbackbuffer 缓冲区添加到队列。缓冲区的大小必须符合上述值。

公众最后的空白自动对焦camera.autofocuscallbackCB)

加入API级别1

启动相机自动对焦和注册一个回调函数运行时,相机聚焦。这种方法是唯一有效的预览时主动(之间startpreview()和之前stoppreview()

用户应该检查getfocusmode()为了确定这种方法被称为。如果相机不支持自动对焦,这是一个没有OPonautofocus(布尔,相机)回调会被立刻

如果你的应用程序不应安装在设备没有自动对焦,你必须声明你的应用程序使用自动对焦的<uses-feature>表现元素

如果当前的闪光模式是不闪光灯关闭模式_ _Flash可以被解雇,在自动对焦,根据司机和相机硬件。

自动曝光锁定getautoexposurelock()自动白平衡锁getautowhitebalancelock()不在自动对焦和之后的变化。但自动对焦程序可能停止自动曝光和自动白平衡瞬时在聚焦。

停止预览stoppreview(),或触发静止图像捕捉(camera.shuttercallback TakePicture、拍照、产生图片时触发,相机。picturecallback),不会改变焦点位置。应用程序必须调用cancelautofocus重置的焦点。

如果对焦成功,可以考虑使用mediaactionsound正确播放自动对焦成功的声音给用户。

参数
CB 回调运行

公众最后的空白cancelautofocus()

加入5级的API

取消任何自动对焦功能的进展。是否自动对焦是目前正在进行中,该函数将返回到默认的焦点位置。如果相机不支持自动对焦,这是一个空操作。

public final布尔enableshuttersound(布尔启用)

启用或禁用默认的快门声拍照的时候。

默认情况下,相机是系统定义的相机的快门声时(camera.shuttercallback TakePicture、拍照、产生图片时触发,相机。picturecallback)被称为。使用这种方法,快门声可以被禁用。这是强烈建议选择快门声音了camera.shuttercallback当系统的快门声被禁用。

请注意,设备可能不总是允许禁用相机快门声。如果快门声音状态不能设置为所需的值,此方法将返回false。candisableshuttersound可以用来确定设备是否会让快门声被禁用。

参数
启用 相机是否应该发挥系统的快门声时TakePicture被称为
退货
  • 真正的如果快门声音状态更改成功。如果快门声音状态是不能改变的。真正的也就是如果快门声音播放已设置为请求的状态恢复。

public static voidgetcamerainfo(int cameraid,camera.camerainfocamerainfo)

加入API级别9

返回有关特定相机的信息。如果getnumberofcameras()返回N、有效的ID是0到n-1。

public static intgetnumberofcameras()

加入API级别9

返回物理相机可以在数本装置。

公共相机参数得到相机的参数()

加入API级别1

返回此相机服务的当前设置。如果修改了返回的参数,它们必须通过setparameters(相机参数)生效

公众最后的空白锁具()

加入5级的API

重新锁定相机防止其他进程访问它。相机的默认对象锁定unlock()被称为。通常reconnect()代替

由于API级别14,相机会自动锁定应用程序start()。应用程序可以使用相机(如:缩放)后开始录音。没有必要把这记录开始或停止后。

如果你不能录制视频,你可能不需要这种方法。

抛出
运行期异常 如果相机不能重新锁定(例如,如果相机仍然被另一个进程使用)。

公共静态相机开放(int cameraid)

加入API级别9

创建一个新的相机对象访问特定硬件的相机。如果相同的相机是由其他应用程序打开,这将抛出一个RuntimeException。

你必须调用release()当你使用完相机,否则将被锁定,无法使用其他应用程序。

你的程序应该只有一个相机对象主动在一个特定的硬件相机时间。

从其他方法回调传递到线程称为open()事件循环。如果线程没有事件循环,然后回调传递到主应用程序事件循环。如果没有主应用程序事件循环,回调不交付。

谨慎:在一些设备上,这个方法可能需要很长的时间来完成。最好是叫一个工作线程(可能使用这种方法异步任务)以避免阻塞UI线程的主要应用。

参数
cameraid 相机的硬件访问,在0getnumberofcameras()- 1
退货
  • 一个新的相机连接,锁定对象,并准备使用。
抛出
运行期异常 如果打开相机失败(例如,如果相机在使用由另一个进程或设备策略管理器禁用了相机)。

公共静态相机开放()

加入API级别1

创建一个新的相机对象访问第一个背对着设备上的照相机。如果设备没有后置摄像头,这将返回null。

公众最后的空白重新连接()

重新连接到相机服务后,另一个进程使用它。后unlock()被称为另一个进程可以使用相机;当过程完成后,您必须重新连接到相机,这将重新获取锁并允许你继续使用相机。

由于API级别14,相机会自动锁定应用程序start()。应用程序可以使用相机(如:缩放)后开始录音。没有必要把这记录开始或停止后。

如果你不能录制视频,你可能不需要这种方法。

抛出
IOException 如果无法连接重新建立(例如,如果相机仍然被另一个进程使用)。

公众最后的空白发布()

加入API级别1

断开并释放相机的对象资源。

你必须把这当你完成摄像机的对象。

公共无效setautofocusmovecallbackcamera.autofocusmovecallbackCB)

设置相机自动对焦移回调。

参数
CB 回调运行

公众最后的空白setdisplayorientation(int度)

设置预览显示顺时针旋转度。这会影响预览框显示在快照图片。这种方法适用于纵向模式的应用。注意,前置摄像头预览显示水平翻转在旋转,即图像反映在相机传感器的中心垂直轴。因此,用户可以看到自己的镜子。

这并不影响字节数组传入的顺序onpreviewframe(byte [],相机)JPEG图片或录制的视频。这种方法不允许被称为预览时。

如果你想使摄像机的图像显示在同一方向的显示,你可以使用下面的代码。

公共静态无效setcameradisplayorientation活动活动
intcameraid安卓硬件相机相机{
安卓硬件相机camerainfo信息=
安卓硬件相机camerainfo();
安卓硬件相机getcamerainfocameraid信息);
int旋转=活动getwindowmanager()getdefaultdisplay()
getrotation();
int=
开关旋转{
案例表面旋转_ 0=打破
案例表面_旋转90=九十打破
案例表面_旋转180=一百八十打破
案例表面旋转_ 270=二百七十打破
}

int结果
如果信息面对==相机camerainfocamera_facing_front{
结果=信息取向 %三百六十
结果=三百六十结果%三百六十/ /补偿镜
}其他的{/ /背面
结果=信息取向 三百六十%三百六十
}
相机setdisplayorientation结果);
}

从API级别14,这种方法可以称为当预览活动。

参数
这幅画将顺时针旋转的角度。有效值是0,90,180,和270。起始位置是0(景观)。

公众最后的空白seterrorcallbackcamera.errorcallbackCB)

加入API级别1

注册一个回调函数被调用时发生错误。

参数
CB 回调运行

公众最后的空白setfacedetectionlistenercamera.facedetectionlistener听众)

注册一个监听器被通知在预览框中检测到的面孔。

参数
听众 听者通知

公众最后的空白setoneshotpreviewcallbackcamera.previewcallbackCB)

安装一个回调是为下一个预览除了显示在屏幕框架调用。之后的一个调用,回调了。这种方法可以称为“任何时候,即使是住在预览。其他预览回调可以重写。

如果您使用的是预览数据创建视频或静止图像,强烈考虑使用mediaactionsound为了正确反映图像捕捉或记录开始/停止给用户。

参数
CB 回调对象,收到下一个预览框,或空停止接收回调。

公共无效setparameters相机参数参数)

加入API级别1

更改此相机服务设置

参数
参数 该参数用于此相机服务
抛出
运行期异常 如果任何参数无效或不被支持。

公众最后的空白setpreviewcallbackcamera.previewcallbackCB)

加入API级别1

安装一个回调是除了显示屏幕上的每个预览框架调用。回调将多次呼吁只要预览活动。这种方法可以在任何时间,甚至在预览是活的。其他预览回调可以重写。

如果您使用的是预览数据创建视频或静止图像,强烈考虑使用mediaactionsound为了正确反映图像捕捉或记录开始/停止给用户。

参数
CB 回调对象的副本的预览框,或空停止接收回调。

公众最后的空白setpreviewcallbackwithbuffercamera.previewcallbackCB)

安装一个回调是为每个预览框架调用,使用缓冲区提供addcallbackbuffer(byte []),除了显示在屏幕上。回调将多次呼吁只要预览活动,缓冲区可用。其他预览回调可以重写。

这种方法的目的是提高效率,通过允许预览预览帧存储器复用帧速率。你必须调用addcallbackbuffer(byte [])在一些点,之前或调用此方法后,没有回调将收到。

缓冲区队列将被清除,如果这种方法被称为一个空的回调,setpreviewcallback(相机。previewcallback)叫,或setoneshotpreviewcallback(camera.previewcallback)被称为

如果您使用的是预览数据创建视频或静止图像,强烈考虑使用mediaactionsound为了正确反映图像捕捉或记录开始/停止给用户。

参数
CB 回调对象收到一份预览框,或空停止接收回调和清除缓冲区队列。

公众最后的空白setpreviewdisplaySurfaceHolder.lockCanvas持有人)

加入API级别1

表面用于实时预览。一个表面或表面纹理是必要的预览,预览是必要的拍照。相同的表面可以不伤害再定。设置预览将不设置任何表面的表面纹理,并通过设置预览setpreviewtexture(表面)

这个SurfaceHolder.lockCanvas必须已经包含一个表面时,调用此方法。如果你使用的是SurfaceView,你都需要登记回调SurfaceHolder。addCallback(SurfaceHolder。回调)等待surfacecreated(SurfaceHolder)在启动呼叫setpreviewdisplay(或预览)。

这个方法必须调用之前startpreview()。唯一的例外是,如果没有设置预览表面(或设置为null)在startpreview()叫,那么这种方法可能是一个非空参数设置预览表面曾经称。(这让相机设置和表面生成发生在平行的,节省时间。)预览表面不得同时预览运行变化。

参数
持有人 含有表面上放置的预览,或空删除预览表
抛出
IOException 如果这个方法失败(例如,如果表面不可用或不适合)。

公众最后的空白setpreviewtexture表面结构表面结构)

表面结构用于实时预览。一个表面或表面纹理是必要的预览,预览是必要的拍照。相同的表面纹理可以不伤害再定。设置预览表面纹理将联合国设置任何,通过预览表setpreviewdisplay(surfaceholder)

这个方法必须调用之前startpreview()。唯一的例外是,如果没有设置预览表面纹理(或设置为null)在startpreview()叫,那么这种方法可能是一个非空参数设置预览表面曾经称。(这让相机设置和表面生成发生在平行的,节省时间。)预览表面纹理可能没有在预览运行变化。

提供的时间戳gettimestamp()一个表面设置为预览纹理有未知的零点,并不能直接比较不同的相机或同一相机的不同实例之间,或在多个运行相同的程序。

如果您使用的是预览数据创建视频或静止图像,强烈考虑使用mediaactionsound为了正确反映图像捕捉或记录开始/停止给用户。

参数
表面结构 这个表面结构该预览图像将被发送或空删除当前预览的表面纹理
抛出
IOException 如果这个方法失败(例如,如果表面纹理不可用或不适合)。

公众最后的空白setzoomchangelistenercamera.onzoomchangelistener听众)

注册侦听器时要通知缩放值更新摄像头驱动在平滑缩放。

参数
听众 听者通知

公众最后的空白startfacedetection()

开始的人脸检测。这应该是预览之后开始叫。相机会通知camera.facedetectionlistener在预览框中检测出人脸的。检测到的面部会像以往一样。应用程序应该调用stopfacedetection()停止的人脸检测。这种方法支持如果getmaxnumdetectedfaces()返回一个数大于0。如果人脸检测已经开始,应用程序不应该叫了。

当人脸检测运行,setwhitebalance(字符串)setfocusareas(list),和setmeteringareas(名单)有没有影响。该相机采用的人脸进行自动白平衡,自动曝光和自动对焦。

如果应用程序调用自动对焦(autofocuscallback),相机会停止发送面临回调。最后面临回调表明用来做自动对焦区域。重点完成人脸检测后,将继续发送面临回调。如果应用程序调用cancelautofocus()面对回调,也将恢复

在调用(camera.shuttercallback TakePicture、拍照、产生图片时触发,相机。picturecallback)stoppreview(),然后恢复预览startpreview(),应用程序应该调用这个方法恢复人脸检测。

抛出
illegalargumentexception 如果人脸检测是不支持的。
运行期异常 如果这个方法失败或人脸检测已经运行。

公众最后的空白开始预览()

加入API级别1

公众最后的空白startsmoothzoom(int值)

放大到要求值平稳。司机会通知camera.onzoomchangelistener的缩放值是否和变焦停止时间。例如,假设当前缩放为0,startsmoothzoom叫做价值3。这个onzoomchange(int,boolean,相机)方法将被调用三次缩放值1,2,和3。应用程序可以调用stopsmoothzoom()停止变焦早。应用程序不应再打startsmoothzoom或改变缩放值在变焦停止。如果提供的缩放值等于当前的缩放值,没有放大回调将产生。这种方法支持如果issmoothzoomsupported()返回true

参数
价值 缩放值。有效的范围是0到getmaxzoom()
抛出
illegalargumentexception 如果缩放值是无效的
运行期异常 如果这个方法失败

公众最后的空白stopfacedetection()

the Face检测停止。

公众最后的空白停止预览()

加入API级别1

停止捕获和图纸预览框的表面,并将相机未来的呼叫startpreview()

公众最后的空白stopsmoothzoom()

停止平滑缩放。应用程序应该等待camera.onzoomchangelistener知道变焦其实是停下来的时候。这种方法支持如果issmoothzoomsupported()是真的

抛出
运行期异常 如果这个方法失败

公众最后的空白TakePicturecamera.shuttercallback快门,拍照、产生图片时触发原,拍照、产生图片时触发JPEG)

加入API级别1

相当于TakePicture(快门,原,null,JPEG)。

公众最后的空白TakePicturecamera.shuttercallback快门,拍照、产生图片时触发原,拍照、产生图片时触发postview,拍照、产生图片时触发JPEG)

加入5级的API

触发器的异步图像捕捉。摄像服务将引发一系列的回调应用作为图像采集的进展。快门回调发生后的图像被捕获。这可以用来触发一个声音让用户知道图像已被抓获。原回调发生时,原始图像数据是可用的(注:数据将是null,如果没有原图像回调缓冲区可用或原始图像回调缓冲区不足以容纳原图像)。的postview回调时发生的比例,完全处理postview图像资料(注意:不是所有的硬件支持)。JPEG压缩图像的回调发生时可用。如果应用程序不需要一个特定的回调,空可以通过代替回调方法。

这种方法是唯一有效的预览活动时(后startpreview())。预览将图片后停止;用户必须调用startpreview()如果他们想重新开始预览或拍更多的照片。这不应该被称为之间start()停止()

调用此方法后,你必须不叫startpreview()或采取另一张图片到JPEG回调回来了。

参数
快门 图像捕捉瞬间的回调,或空
原回调(压缩)的图像数据,或空
postview 与postview图像数据的回调,可能是空的
JPEG JPEG图像数据的回调,或空

公众最后的空白解锁()

加入5级的API

打开相机允许另一个进程访问它。通常情况下,镜头锁定在与主动摄像机目标前的过程release()被称为。允许进程间快速切换,你可以调用这个方法来释放相机暂时的另一个过程使用;一旦其他进程完成后你可以打电话reconnect()回收相机

这必须在调用setcamera(相机)。这不能称为记录后开始。

如果你不能录制视频,你可能不需要这种方法。

抛出
运行期异常 如果相机不能解锁

保护的方法

protected void完成()

加入API级别1

当调用垃圾收集器发现这个实例不可达。默认实现不执行任何操作,但可以重写该方法来释放资源。

注意,对象覆盖完成比的对象,没有终结器的对象后,可以运行很长一段时间更昂贵的不再是可达的,这取决于内存的压力,所以它是依靠他们清理一个坏主意。注意,程序运行在一台虚拟机宽终结器线程,这样堵在终结器的工作是一个坏主意。终结器通常只需要一个类有一个本地的同行和需要调用本地方法来消灭同行。即使这样,最好是提供一个明确的关闭(与实现方法闭合),坚持用户手动处理实例。这对于类似的文件,但更像一个BigInteger其中的典型调用代码会处理很多临时性的问题。不幸的是,代码创建很多临时性的问题是最严重的单一的终结器线程的角度编码。

如果你必须使用终结器,至少考虑提供自己的并拥有自己的线程队列。

与构造函数,析构函数不会自动锁。你是负责调用super.finalize()你自己

未捕获的异常被忽略和不终止程序终结器线程。看到通用程序设计第7项“避免finalizers”更多。



2018-04-11 20:57:00 weixin_34246551 阅读数 22

作者:某人_Valar
如需转载请保留原文链接;

在Android的开发过程中,目前使用相机大概分为两种方式,一种是直接拉起系统的相机进行拍照,另一种就是自定义一个相机界面。

关于自定义相机的使用:

在自定义相机中我们就可以自定义拍照的界面,设置拍照的参数等。


6502966-3503e21d7a94a275.png
一个自定义的相机界面

主要是一个自定义的Activity,

  1. 使用CameraPreview 进行预览,
  2. 然后调用Camera的takePicture方法拍照,
  3. 之后再对应的回调中保存或者展示即可。
public class CameraActivity extends Activity {
    protected static final String TAG = "raycamera";
    private Camera mCamera;
    private int cameraPosition = 0;//0代表后置摄像头,1代表前置摄像头
    private SurfaceHolder mHolder;
    static CameraActivity mInstance = null;
    private File compressFile;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);
        ButterKnife.bind(this);

        CameraPreview mPreview = new CameraPreview(this);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.addView(mPreview);
        mInstance = this;
    }

    public static Camera getCameraInstance() {
        Camera c = null;
        try {
            c = Camera.open(0);
        } catch (Exception e) {
            // Camera is notavailable (in use or does not exist)
        }
        return c;
    }

    @OnClick(R.id.capture_iv)
    void takePic() {
        mCamera.takePicture(null, null, mPicture);
        tip("拍照中,请保持手机稳定");
    }

    //点击屏幕进行对焦
    @OnClick(R.id.camera_preview)
    void autoFocus() {
        try {
            mCamera.autoFocus(autoFocusCallback);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @OnClick(R.id.changeCamera_iv)
    void changeCamera() {
        //切换前后摄像头
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        int cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数
        for (int i = 0; i < cameraCount; i++) {
            Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息
            if (cameraPosition == 0) {
                //现在是后置,变更为前置
                if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                    if (mCamera != null) {
                        mCamera.stopPreview();//停掉原来摄像头的预览
                        mCamera.release();//释放资源
                        mCamera = null;//取消原来摄像头
                    }
                    Log.d(TAG, "open front ,i = " + i);
                    mCamera = Camera.open(i);//打开当前选中的摄像头
                    try {
                        mCamera.setPreviewDisplay(mHolder);//通过surfaceview显示取景画面
                        mCamera.setDisplayOrientation(90);
                        setCameraParms(mCamera);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    mCamera.startPreview();//开始预览
                    cameraPosition = 1;
                    break;
                }
            } else {
                //现在是前置, 变更为后置
                if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                    if (mCamera != null) {
                        mCamera.stopPreview();//停掉原来摄像头的预览
                        mCamera.release();//释放资源
                        mCamera = null;//取消原来摄像头
                    }
                    Log.d(TAG, "open back ,i = " + i);
                    mCamera = Camera.open(i);//打开当前选中的摄像头
                    try {
                        mCamera.setPreviewDisplay(mHolder);//通过surfaceview显示取景画面
                        mCamera.setDisplayOrientation(90);
                        setCameraParms(mCamera);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    mCamera.startPreview();//开始预览
                    cameraPosition = 0;
                    break;
                }
            }
        }
    }

    public class CameraPreview extends SurfaceView implements
            SurfaceHolder.Callback {
        // private Camera mCamera;
        public CameraPreview(Context context) {
            super(context);
            //mCamera = camera;
            mHolder = getHolder();
            mHolder.addCallback(this);
            // deprecatedsetting, but required on Android versions prior to 3.0
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        public void surfaceCreated(SurfaceHolder holder) {
            Log.d(TAG, "surfaceCreated: ");
            cameraPosition = 0;//创建时设置默认后置摄像头
            mCamera = getCameraInstance();

            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.setDisplayOrientation(90);
                mCamera.startPreview();
            } catch (IOException e) {
                Log.d(TAG, "Errorsetting camera preview: " + e.getMessage());
            }
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
            Log.d(TAG, "surfaceDestroyed: ");
            if (mCamera != null) {
                mCamera.release();
                mCamera = null;
            }
        }

        public void surfaceChanged(SurfaceHolder holder, int format, int w,
                                   int h) {
            // If your preview can change or rotate, take care of those events here.
            // Make sure to stop the preview before resizing or reformatting it.
            Log.d(TAG, "surfaceChanged ");
            if (mHolder.getSurface() == null) {
                return;
            }

            try {
                mCamera.stopPreview();
            } catch (Exception e) {
                // ignore: triedto stop a non-existent preview
            }

            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.setDisplayOrientation(90);
                mCamera.startPreview();
                setCameraParms(mCamera);
            } catch (Exception e) {
                Log.d(TAG, "Errorstarting camera preview: " + e.getMessage());
            }
        }
    }

    private void setCameraParms(Camera camera) {
        Camera.Parameters params = camera.getParameters();
        //设置相机保存图片的尺寸大小
        List<Camera.Size> supportSizes = params.getSupportedPictureSizes();
        Camera.Size bestSize = supportSizes.get(0);
        for (int i = 1; i < supportSizes.size(); i++) {
            if ((supportSizes.get(i).width * supportSizes.get(i).height) > (bestSize.width * bestSize.height)) {
                bestSize = supportSizes.get(i);
            }
        }
        params.setPictureSize(bestSize.width, bestSize.height);
        camera.setParameters(params);
    }

    Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {

        @Override
        public void onAutoFocus(boolean success, Camera camera) {

        }
    };

    //拍照结束后的回调
    private PictureCallback mPicture = new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            camera.stopPreview();
            File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/songshucang");
            boolean isFileCreated = file.exists();
            if (!isFileCreated) {
                isFileCreated = file.mkdir();
            }
            if (isFileCreated) {
                Bitmap bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0);
                final Matrix matrix = new Matrix();
                if (cameraPosition == 0) {
                    matrix.setRotate(90);
                } else {
                    matrix.setRotate(270);
                }
                final Bitmap bitmap =
                        Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);

                String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA)
                        .format(new Date());
                String photoPath = file + "/ssc/IMG_" + timeStamp;
                try {
                    saveImageToSD(CameraActivity.this,
                            photoPath, bitmap, 90);
                    //拍照完成后用广播通知系统相册更新,否则可能在相册中看不见刚保存的图片
                    File fileTemp = new File(photoPath);
                    Uri uri =  Uri.fromFile(fileTemp);  
                    Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                    intent.setData(uri);
                    CameraActivity.this.sendBroadcast(intent);
                } catch (FileNotFoundException e) {
                    Log.i("cameratest", "File notfound: " + e.getMessage());
                } catch (IOException e) {
                    Log.i("cameratest", "Erroraccessing file: " + e.getMessage());
                }
            }
        }
    };

    //保存图片
    public void saveImageToSD(String filePath,
                              Bitmap bitmap, int quality) throws IOException {
        if (bitmap != null) {
            File file = new File(filePath.substring(0,
                    filePath.lastIndexOf(File.separator)));
            if (!file.exists()) {
                file.mkdirs();
            }
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream(filePath));
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, bos);
            bos.flush();
            bos.close();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }


}

布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent" >

        <FrameLayout
            android:id="@+id/camera_preview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            >
        </FrameLayout>

        <ImageView
            android:layout_width="380px"
            android:layout_height="472px"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:src="@drawable/bg_face"/>

        <RelativeLayout
            android:id="@+id/capture_rl"
            android:background="#50000000"
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:layout_alignParentBottom="true">

            <ImageView
                android:id="@+id/choose_photo_iv"
                android:src="@drawable/ic_album"
                android:layout_width="45dp"
                android:layout_height="36dp"
                android:layout_alignParentLeft="true"
                android:layout_centerVertical="true"
                android:layout_marginLeft="50dp"/>

            <ImageView
                android:src="@drawable/ic_photograph"
                android:id="@+id/capture_iv"
                android:layout_width="64dp"
                android:layout_height="64dp"
                android:layout_centerInParent="true"
                />

            <ImageView
                android:src="@drawable/ic_camera_transform"
                android:id="@+id/changeCamera_iv"
                android:layout_width="45dp"
                android:layout_height="36dp"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_marginRight="50dp"/>

</RelativeLayout>

有时候我们会发现拍照保存的图片在相册中查看不到,这是因为没有通知系统相册更新。

       //拍照完成后用广播通知系统相册更新
       File fileTemp = new File(photoPath);
       Uri uri =  Uri.fromFile(fileTemp);  
       Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
       intent.setData(uri);
       CameraActivity.this.sendBroadcast(intent);

相机android 相关内容

2011-10-21 17:11:29 haojunming 阅读数 68

相机android 相关内容

2018-04-11 21:09:40 sxl871532815 阅读数 108

作者:sxl
如需转载请保留原文链接;

在Android的开发过程中,目前使用相机大概分为两种方式,一种是直接拉起系统的相机进行拍照,另一种就是自定义一个相机界面。

关于自定义相机的使用:

在自定义相机中我们就可以自定义拍照的界面,设置拍照的参数等。
一个自定义的相机界面

主要是一个自定义的Activity,
1. 使用CameraPreview 进行预览,
2. 然后调用Camera的takePicture方法拍照,
3. 之后再对应的回调中保存或者展示即可。

public class CameraActivity extends Activity {
    protected static final String TAG = "raycamera";
    private Camera mCamera;
    private int cameraPosition = 0;//0代表后置摄像头,1代表前置摄像头
    private SurfaceHolder mHolder;
    static CameraActivity mInstance = null;
    private File compressFile;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);
        ButterKnife.bind(this);

        CameraPreview mPreview = new CameraPreview(this);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.addView(mPreview);
        mInstance = this;
    }

    public static Camera getCameraInstance() {
        Camera c = null;
        try {
            c = Camera.open(0);
        } catch (Exception e) {
            // Camera is notavailable (in use or does not exist)
        }
        return c;
    }

    @OnClick(R.id.capture_iv)
    void takePic() {
        mCamera.takePicture(null, null, mPicture);
        tip("拍照中,请保持手机稳定");
    }

    //点击屏幕进行对焦
    @OnClick(R.id.camera_preview)
    void autoFocus() {
        try {
            mCamera.autoFocus(autoFocusCallback);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @OnClick(R.id.changeCamera_iv)
    void changeCamera() {
        //切换前后摄像头
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        int cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数
        for (int i = 0; i < cameraCount; i++) {
            Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息
            if (cameraPosition == 0) {
                //现在是后置,变更为前置
                if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                    if (mCamera != null) {
                        mCamera.stopPreview();//停掉原来摄像头的预览
                        mCamera.release();//释放资源
                        mCamera = null;//取消原来摄像头
                    }
                    Log.d(TAG, "open front ,i = " + i);
                    mCamera = Camera.open(i);//打开当前选中的摄像头
                    try {
                        mCamera.setPreviewDisplay(mHolder);//通过surfaceview显示取景画面
                        mCamera.setDisplayOrientation(90);
                        setCameraParms(mCamera);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    mCamera.startPreview();//开始预览
                    cameraPosition = 1;
                    break;
                }
            } else {
                //现在是前置, 变更为后置
                if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                    if (mCamera != null) {
                        mCamera.stopPreview();//停掉原来摄像头的预览
                        mCamera.release();//释放资源
                        mCamera = null;//取消原来摄像头
                    }
                    Log.d(TAG, "open back ,i = " + i);
                    mCamera = Camera.open(i);//打开当前选中的摄像头
                    try {
                        mCamera.setPreviewDisplay(mHolder);//通过surfaceview显示取景画面
                        mCamera.setDisplayOrientation(90);
                        setCameraParms(mCamera);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    mCamera.startPreview();//开始预览
                    cameraPosition = 0;
                    break;
                }
            }
        }
    }

    public class CameraPreview extends SurfaceView implements
            SurfaceHolder.Callback {
        // private Camera mCamera;
        public CameraPreview(Context context) {
            super(context);
            //mCamera = camera;
            mHolder = getHolder();
            mHolder.addCallback(this);
            // deprecatedsetting, but required on Android versions prior to 3.0
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        public void surfaceCreated(SurfaceHolder holder) {
            Log.d(TAG, "surfaceCreated: ");
            cameraPosition = 0;//创建时设置默认后置摄像头
            mCamera = getCameraInstance();

            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.setDisplayOrientation(90);
                mCamera.startPreview();
            } catch (IOException e) {
                Log.d(TAG, "Errorsetting camera preview: " + e.getMessage());
            }
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
            Log.d(TAG, "surfaceDestroyed: ");
            if (mCamera != null) {
                mCamera.release();
                mCamera = null;
            }
        }

        public void surfaceChanged(SurfaceHolder holder, int format, int w,
                                   int h) {
            // If your preview can change or rotate, take care of those events here.
            // Make sure to stop the preview before resizing or reformatting it.
            Log.d(TAG, "surfaceChanged ");
            if (mHolder.getSurface() == null) {
                return;
            }

            try {
                mCamera.stopPreview();
            } catch (Exception e) {
                // ignore: triedto stop a non-existent preview
            }

            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.setDisplayOrientation(90);
                mCamera.startPreview();
                setCameraParms(mCamera);
            } catch (Exception e) {
                Log.d(TAG, "Errorstarting camera preview: " + e.getMessage());
            }
        }
    }

    private void setCameraParms(Camera camera) {
        Camera.Parameters params = camera.getParameters();
        //设置相机保存图片的尺寸大小
        List<Camera.Size> supportSizes = params.getSupportedPictureSizes();
        Camera.Size bestSize = supportSizes.get(0);
        for (int i = 1; i < supportSizes.size(); i++) {
            if ((supportSizes.get(i).width * supportSizes.get(i).height) > (bestSize.width * bestSize.height)) {
                bestSize = supportSizes.get(i);
            }
        }
        params.setPictureSize(bestSize.width, bestSize.height);
        camera.setParameters(params);
    }

    Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {

        @Override
        public void onAutoFocus(boolean success, Camera camera) {

        }
    };

    //拍照结束后的回调
    private PictureCallback mPicture = new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            camera.stopPreview();
            File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/songshucang");
            boolean isFileCreated = file.exists();
            if (!isFileCreated) {
                isFileCreated = file.mkdir();
            }
            if (isFileCreated) {
                Bitmap bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0);
                final Matrix matrix = new Matrix();
                if (cameraPosition == 0) {
                    matrix.setRotate(90);
                } else {
                    matrix.setRotate(270);
                }
                final Bitmap bitmap =
                        Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);

                String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA)
                        .format(new Date());
                String photoPath = file + "/ssc/IMG_" + timeStamp;
                try {
                    saveImageToSD(CameraActivity.this,
                            photoPath, bitmap, 90);
                    //拍照完成后用广播通知系统相册更新,否则可能在相册中看不见刚保存的图片
                    File fileTemp = new File(photoPath);
                    Uri uri =  Uri.fromFile(fileTemp);  
                    Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                    intent.setData(uri);
                    CameraActivity.this.sendBroadcast(intent);
                } catch (FileNotFoundException e) {
                    Log.i("cameratest", "File notfound: " + e.getMessage());
                } catch (IOException e) {
                    Log.i("cameratest", "Erroraccessing file: " + e.getMessage());
                }
            }
        }
    };

    //保存图片
    public void saveImageToSD(String filePath,
                              Bitmap bitmap, int quality) throws IOException {
        if (bitmap != null) {
            File file = new File(filePath.substring(0,
                    filePath.lastIndexOf(File.separator)));
            if (!file.exists()) {
                file.mkdirs();
            }
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream(filePath));
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, bos);
            bos.flush();
            bos.close();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }


}

布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent" >

        <FrameLayout
            android:id="@+id/camera_preview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            >
        </FrameLayout>

        <ImageView
            android:layout_width="380px"
            android:layout_height="472px"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:src="@drawable/bg_face"/>

        <RelativeLayout
            android:id="@+id/capture_rl"
            android:background="#50000000"
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:layout_alignParentBottom="true">

            <ImageView
                android:id="@+id/choose_photo_iv"
                android:src="@drawable/ic_album"
                android:layout_width="45dp"
                android:layout_height="36dp"
                android:layout_alignParentLeft="true"
                android:layout_centerVertical="true"
                android:layout_marginLeft="50dp"/>

            <ImageView
                android:src="@drawable/ic_photograph"
                android:id="@+id/capture_iv"
                android:layout_width="64dp"
                android:layout_height="64dp"
                android:layout_centerInParent="true"
                />

            <ImageView
                android:src="@drawable/ic_camera_transform"
                android:id="@+id/changeCamera_iv"
                android:layout_width="45dp"
                android:layout_height="36dp"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_marginRight="50dp"/>

</RelativeLayout>

有时候我们会发现拍照保存的图片在相册中查看不到,这是因为没有通知系统相册更新。

       //拍照完成后用广播通知系统相册更新
       File fileTemp = new File(photoPath);
       Uri uri =  Uri.fromFile(fileTemp);  
       Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
       intent.setData(uri);
       CameraActivity.this.sendBroadcast(intent);

相机android 相关内容

2011-06-21 14:32:19 iteye_11971 阅读数 30

    在Android中专门提供了Camera来处理相机相关的时间,Camera是一个专门用来连接和断开服务的类,Camera下面包括如下几个事件:

  1. Camera.AutoFocusCallback  自动调焦功能
  2. Camera.ErrorCallback           错误信息扑捉
  3. Camera.parameters             相机的属性参数
  4. Camera.PictureCallback       拍照、产生图片时触发
  5. Camera.ShutterCallback      快门设置
  6. Camera.Size                         图片的尺寸

    要在Android中使用相机服务很简单,Camera没有构造方法,我们要使用它直接通过open()方法来打开相机设备,然后通过Camera.Parameters对相机的一些属性进行设置,比如输出图片的格式,大小等。使用Camera科技型的操作,如下:

   方法                                                                        说明

autoFocus                                                           设置自动对焦

getParameters                                                    得到相机的参数

open                                                                   启动相机服务

release                                                                释放Camera服务

setParameters                                                    设置预览的参数

setPreviewDisplay                                              设置预览

startpreview                                                       开始预览

stopPreview                                                       停止预览

takePicture                                                         拍照

    这里重点说明一下拍照的方法和使用,takepicture方法要实现3个回调函数,分别是:Camera.ShutterCallback(快门)和两个Camera.PictureCallback(图像数据)。这里我们在拍照之后要取得图像数据就需要实现Camera.PictureCallback的onPictureTaken方法。onPictureTaken中第一个参数就是图像数据,第二个参数则是相机。

    下面看一个通过相机拍照的例子,相机需要一个界面来预览当前的拍摄效果,这里可以使用SurfaceView类。

package com.yarin.android.Examples_07_06;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;

public class Activity01 extends Activity
{
	private Preview	mPreview;


	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);

		// Create our Preview view and set it as the content of our activity.
		mPreview = new Preview(this);
		setContentView(mPreview);
	}


	public boolean onKeyUp(int keyCode, KeyEvent event)
	{
		switch (keyCode)
		{
			case KeyEvent.KEYCODE_DPAD_CENTER:
				mPreview.takePicture();
				break;
		}
		return true;
	}
}

/* Preview-显示Preview */
class Preview extends SurfaceView implements SurfaceHolder.Callback 
{
    SurfaceHolder mHolder;
    Camera mCamera;
    Bitmap CameraBitmap;
    
    Preview(Context context) 
    {
        super(context);
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) 
    {
    	/* 启动Camera */
        mCamera = Camera.open();
        try 
        {
           mCamera.setPreviewDisplay(holder);
        } 
        catch (IOException exception) 
        {
        	/* 释放mCamera */
            mCamera.release();
            mCamera = null;
            // TODO: add more exception handling logic here
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) 
    {
    	/* 停止预览 */
        mCamera.stopPreview();
        mCamera = null;
    }    
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) 
    {
    	/* 构建Camera.Parameters对相机的参数进行设置 */
        Camera.Parameters parameters = mCamera.getParameters();
        /* 设置拍照的图片格式 */
        parameters.setPictureFormat(PixelFormat.JPEG);
        /* 设置Preview的尺寸 */
        parameters.setPreviewSize(320, 480);
        /* 设置图像分辨率 */
        //parameters.setPictureSize(320, 480);
        /* 设置相机采用parameters */
        mCamera.setParameters(parameters);
        /* 开始预览 */
        mCamera.startPreview();
    }
    /* 拍照片 */
    public void takePicture() 
    {
      if (mCamera != null) 
      {
    	  mCamera.takePicture(null, null, jpegCallback);
      }
    }
    /* 拍照后输出图片 */
    private PictureCallback jpegCallback = new PictureCallback() 
    {
      public void onPictureTaken(byte[] _data, Camera _camera)
      {
        // TODO Handle JPEG image data
    	CameraBitmap = BitmapFactory.decodeByteArray(_data, 0, _data.length); 
        File myCaptureFile = new File("/sdcard/camera1.jpg");
        try
        {
          BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
          CameraBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
          bos.flush();
          bos.close();
          /* 将拍到的图片绘制出来 */
          Canvas canvas= mHolder.lockCanvas();
          canvas.drawBitmap(CameraBitmap, 0, 0, null);
          mHolder.unlockCanvasAndPost(canvas);
          
        }
        catch (Exception e)
        {
        	e.getMessage();
        }
      }
    };
}

 

相机android 相关内容

activity_main.xml

博文 来自: Taily_Duan
没有更多推荐了,返回首页