• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Android开发技巧之Camera拍照功能

Android开发技巧之Camera拍照功能

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android开发技巧,android开发支付功能,android开发聊天功能,android开发 筛选功能,android开发搜索功能等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Android开发技巧之Camera拍照功能


本篇是我对开发项目的拍照功能过程中,对Camera拍照使用的总结。由于camera2是在api level 21(5.0.1)才引入的,而Camera到6.0仍可使用,所以暂未考虑camera2。


文档中的Camera

相对于其他绝大多数类,文档对Camera的介绍还是比较详尽的,包含了使用过程中所需要的步骤说明,当然,这也表明了它在实际使用中的繁琐。
首先,需要在AndroidManifest.xml中声明以下权限和特性:

 
 
 

然后,拍照的话,需要以下十步:
1. 通过open(int)方法得到一个实例
2. 通过getParameters()方法得到默认的设置
3. 如果有必要,修改上面所返回的Camera.Parameters对象,并调用setParameters(Camera.Parameters) 进行设置
4. 如果有需要,调用setDisplayOrientation(int)设置显示的方向
5. 这一步很重要,通过setPreviewDisplay(SurfaceHolder)传入一个已经初始化了的SurfaceHolder,否则无法进行预览。
6. 这一步也很重要,通过startPreview()开始更新你的预览界面,在你拍照之前,它必须开始。
7. 调用takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback)进行拍照,等待它的回调
8. 拍照之后,预览的展示会停止。如果想继续拍照,需要先再调用startPreview()。
9. 调用stopPreview()停止预览。
10. 非常重要,调用release()释放Camera,以使其他应用也能够使用相机。你的应用应该在onPause()被调用时就进行释放,在onResume()时再重新open()。

上面就是文档中关于使用Camera进行拍照的介绍了。接下来说一下我的使用场景。

我的使用场景

这里写图片描述
这是项目的界面需求。下面一个圆的拍照按钮,然后是一个取消按钮,上面是预览界面(SurfaceView)加个取景框。再上面就是一块黑的了。点拍照,拍照之后,跳到一个裁剪图片的界面,所以不会有连续拍多次照片的场景。
取景框什么的这里略过不谈,布局文件也相对比较简单,下面直接看Java代码里对Camera的使用。

实际使用及填坑

SurfaceHolder的回调

我在Activity中实现SurfaceHolder.Callback接口。然后在onCreate(Bundle)方法中,添加SurfaceHolder的回调。

        SurfaceHolder holder = mSurfaceView.getHolder();
        holder.addCallback(this);

它的回调方法有3个,分别是surface被创建时的回调surfaceCreated(SurfaceHolder),surface被销毁时的回调surfaceDestroyed(SurfaceHolder)以及surface改变时的回调surfaceChanged(SurfaceHolder holder, int, int, int)。这里我们只关注创建和销毁时的回调,定义一个变量用于标志它的状态。

    private boolean mIsSurfaceReady;

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mIsSurfaceReady = true;
        startPreview();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mIsSurfaceReady = false;
    }

其中的startPreview()方法将在下面讲到。

打开相机

然后是打开相机。这些代码在我定义的openCamera方法中。

        if (mCamera == null) {
            try {
                mCamera = Camera.open();
            } catch (RuntimeException e) {
                if ("Fail to connect to camera service".equals(e.getMessage())) {
                    //提示无法打开相机,请检查是否已经开启权限
                } else if ("Camera initialization failed".equals(e.getMessage())) {
                    //提示相机初始化失败,无法打开
                } else {
                    //提示相机发生未知错误,无法打开
                }
                finish();
                return;
            }
        }

打开相机失败的话,我们无法进行下一步操作,所以在提示之后会直接把界面关掉。

拍照参数

        final Camera.Parameters cameraParams = mCamera.getParameters();
        cameraParams.setPictureFormat(ImageFormat.JPEG);
        cameraParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

分别设置图片格式,以及对焦模式。然后因为我这里是竖屏拍照,所以还需要对Camera旋转90度。

cameraParams.setRotation(90);

注意:涉及到旋转的有两个方法,一个是旋转相机,一个是旋转预览。这里设置的是对相机的旋转。
继续注意:由于机型兼容的问题,这里设置旋转之后,有些手机照片来的照片就是竖的了,但是有些手机(比如万恶的三星)拍出来的照片还是横的,但是它们在照片的Exif信息中有相关的角度属性。所以对于拍出来的照片还是横着的,我们在裁剪时再继续处理。关于照片的旋转处理,后续博客中会讲到。

尺寸参数

这里还是Camera的参数设置,但是我把它单独抽出来是因为,它不像上面设置的参数那样简单直接,而需要进行计算。下面是我们需要注意的问题:

首先,相机的宽高比例主要有两种,一种是16:9,一种是4:3。其次,我们需要SurfaceView的比例与Camera预览尺寸的比例一样,才不会导致预览出来的结果是变形的。由于机型分辨率的问题,再加上我们的SurfaceView不是满屏的(即使满屏,还要考虑一些虚拟导航栏和各种奇葩分辨率的机型),16:9的比例我们需要上是不会用到的了,我们会让Camera预览的尺寸比例与SurfaceView的大小比例一样。要特别注意,一些手机,如果设置预览的大小与设置的图片大小相差太大(但宽高比例相同)的话,拍出来的照片可能范围也不一样。比如你拍的时候明明是一幅画包括画框,保存的图片却只有画框里的内容。

下面的代码还是写在我们的openCamera()方法中。由于我们需要能够获取到SurfaceView的大小,所以openCamera()是这样调用的:

    @Override
    protected void onResume() {
        super.onResume();
        mSurfaceView.post(new Runnable() {
            @Override
            public void run() {
                openCamera();
            }
        });
    }

它可以保证在openCamera()被调用时surfaceView一定是绘制完成了的。
然后在openCamera()的后续代码中,先获取surfaceView的宽高比例。注意,对于surfaceView我开始在布局上写的是高度占满剩下的空间。

    

这时候得到的宽高比就是我们所能接受的最小比例了。

        // 短边比长边
        final float ratio = (float) mSurfaceView.getWidth() / mSurfaceView.getHeight();

然后获取相机支持的图片尺寸,找出最适合的尺寸。

        // 设置pictureSize
        List pictureSizes = cameraParams.getSupportedPictureSizes();
        if (mBestPictureSize == null) {
            mBestPictureSize =findBestPictureSize(pictureSizes, cameraParams.getPictureSize(), ratio);
        }
        cameraParams.setPictureSize(mBestPictureSize.width, mBestPictureSize.height);

findBestPictureSize的代码如下。注意,因为我们是旋转了相机的,所以计算的时候,对surfaceView的比例是宽除以高,而对Camera.Size则是高除以宽。

    /**
     * 找到短边比长边大于于所接受的最小比例的最大尺寸
     *
     * @param sizes       支持的尺寸列表
     * @param defaultSize 默认大小
     * @param minRatio    相机图片短边比长边所接受的最小比例
     * @return 返回计算之后的尺寸
     */
    private Camera.Size findBestPictureSize(List sizes, Camera.Size de



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • android 编程小技巧(持续中)
  • Android开发技巧——大图裁剪
  • Android开发技巧——定制仿微信图片裁剪控件
  • Android开发技巧之Camera拍照功能

相关文章

  • 2017-05-26WebView的使用,WebView使用
  • 2017-05-26Android 支持表情功能
  • 2017-05-26上传图像之裁剪,图像裁剪
  • 2017-05-228.3.5 Paint API之—— Xfermode与PorterDuff详解(二)
  • 2017-05-26银联支付,支付
  • 2017-05-26可展开的列表组件——ExpandableListView深入解析,expandablelist展开
  • 2017-05-26三年0故障总结,提升代码质量的秘诀
  • 2017-05-26Android ListView onItemClick Not Work,androidonitemclick
  • 2017-05-26Docker+Redis3集群环境搭建
  • 2017-07-23Android设计模式(十六)-中介者模式

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 手游助手应用源码项目,游助手源码项目
    • 「视频直播技术详解」系列之五:延迟优化,
    • EventBus简单使用教程
    • Android横竖屏切换小结,Android屏切换小结
    • android基础部分再学习---再谈Service进程服务通信
    • 基于android-async-http的android服务,android-async-http
    • Android动态加载Dex机制解析
    • 开发 Material Design+RxJava+Retrofit+MVP App 参考资料,rxjavaretrofit
    • Android--音乐播放器
    • 安卓蓝牙技术Bluetooth使用流程(Bluetooth详解),安卓bluetooth

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有