• 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 手把手带你玩转自定义相机

Android 手把手带你玩转自定义相机

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

网友通过本文主要向大家介绍了手把手教你学android,android 自定义相机,android调用系统相机,android相机出现问题,android调用相机拍照等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Android 手把手带你玩转自定义相机


概述

相机几乎是每个APP都要用到的功能,万一老板让你定制相机方不方?反正我是有点方。关于相机的两天奋斗总结免费送给你。

启动相机的两种方式

1.直接启动系统相机

  Intent intent = new Intent();  
  intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);  
  startActivity(intent);

或者指定返回图片的名称mCurrentPhotoFile

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(mCurrentPhotoFile));
        startActivityForResult(intent, CAMERA_WITH_DATA);

2.自定义启动相机
今天以第二种为例。效果图如下

demo

自定义相机的一般步骤

创建显示相机画面的布局,Android已经为我们选定好SurfaceView 通过SurfaceView#getHolder()获得链接Camera和SurfaceView的SurfaceHolder Camame.open()打开相机 通过SurfaceHolder链接Camera和SurfaceView

一般步骤的代码演示

public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Camera.AutoFocusCallback {

    private static final String TAG = "CameraSurfaceView";

    private Context mContext;
    private SurfaceHolder holder;
    private Camera mCamera;

    private int mScreenWidth;
    private int mScreenHeight;

    public CameraSurfaceView(Context context) {
        this(context, null);
    }

    public CameraSurfaceView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CameraSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        getScreenMetrix(context);
        initView();
    }

    private void getScreenMetrix(Context context) {
        WindowManager WM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        WM.getDefaultDisplay().getMetrics(outMetrics);
        mScreenWidth = outMetrics.widthPixels;
        mScreenHeight = outMetrics.heightPixels;
    }

    private void initView() {
        holder = getHolder();//获得surfaceHolder引用
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置类型
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.i(TAG, "surfaceCreated");
        if (mCamera == null) {
            mCamera = Camera.open();//开启相机
            try {
                mCamera.setPreviewDisplay(holder);//摄像头画面显示在Surface上
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Log.i(TAG, "surfaceChanged");
        mCamera.startPreview();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.i(TAG, "surfaceDestroyed");
        mCamera.stopPreview();//停止预览
        mCamera.release();//释放相机资源
        mCamera = null;
        holder = null;
    }

    @Override
    public void onAutoFocus(boolean success, Camera Camera) {
        if (success) {
            Log.i(TAG, "onAutoFocus success="+success);
        }
    }
}

添加相机和自动聚焦限权


将CameraSurfaceView放在布局文件中,这里建议最外层为FrameLayout,后面会用到。如此,我们便有了一个没有照相功能的相机。初次之外,仔细观察相机显示画面,图片是不是变形严重?那是因为我们还没有为相机设置各种参数。在预览前要设置摄像头的分辨率、预览分辨率和图片分辨率的宽高比保持一致。这样图片才不会变形。这是个比较难以理解的部分,想深刻理解还需读者自己动手去实践。

   private void setCameraParams(Camera camera, int width, int height) {
        Log.i(TAG,"setCameraParams  width="+width+"  height="+height);
        Camera.Parameters parameters = mCamera.getParameters();
        // 获取摄像头支持的PictureSize列表
        List pictureSizeList = parameters.getSupportedPictureSizes();
        for (Camera.Size size : pictureSizeList) {
            Log.i(TAG, "pictureSizeList size.width=" + size.width + "  size.height=" + size.height);
        }
        /**从列表中选取合适的分辨率*/
        Camera.Size picSize = getProperSize(pictureSizeList, ((float) height / width));
        if (null == picSize) {
            Log.i(TAG, "null == picSize");
            picSize = parameters.getPictureSize();
        }
        Log.i(TAG, "picSize.width=" + picSize.width + "  picSize.height=" + picSize.height);
         // 根据选出的PictureSize重新设置SurfaceView大小
        float w = picSize.width;
        float h = picSize.height;
        parameters.setPictureSize(picSize.width,picSize.height);
        this.setLayoutParams(new FrameLayout.LayoutParams((int) (height*(h/w)), height));

        // 获取摄像头支持的PreviewSize列表
        List previewSizeList = parameters.getSupportedPreviewSizes();

        for (Camera.Size size : previewSizeList) {
            Log.i(TAG, "previewSizeList size.width=" + size.width + "  size.height=" + size.height);
        }
        Camera.Size preSize = getProperSize(previewSizeList, ((float) height) / width);
        if (null != preSize) {
            Log.i(TAG, "preSize.width=" + preSize.width + "  preSize.height=" + preSize.height);
            parameters.setPreviewSize(preSize.width, preSize.height);
        }

        parameters.setJpegQuality(100); // 设置照片质量
        if (parameters.getSupportedFocusModes().contains(android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
            parameters.setFocusMode(android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);// 连续对焦模式
        }

        mCamera.cancelAutoFocus();//自动对焦。
        mCamera.setDisplayOrientation(90);// 设置PreviewDisplay的方向,效果就是将捕获的画面旋转多少度显示
        mCamera.setParameters(parameters);

    }

    /**
     * 从列表中选取合适的分辨率
     * 默认w:h = 4:3
     *

注意:这里的w对应屏幕的height * h对应屏幕的width

*/ private Camera.Size getProperSize(List pictureSizeList, float screenRatio) { Log.i(TAG, "screenRatio=" + screenRatio); Camera.Size result = null; for (Camera.Size size : pictureSizeList) { float currentRatio = ((float) size.width) / size.height; if (currentRatio - screenRatio == 0) { result = size; break; } } if (null == result) { for (Camera.Size size : pictureSizeList) { float curRatio = ((float) size.width) / size.height; if (curRatio == 4f / 3) {// 默认w:h = 4:3 result = size; break; } } } return result; }

进去的是屏幕宽高,出来的是调整好了的参数。在surfaceChanged方法中执行mCamera.startPreview(); 前调用setCameraParams(mCamera, mScreenWidth, mScreenHeight); 就可以了。最后要在AndroidManifest.xml里设置activity的方向android:screenOrientation="portrait"代码里有很多注释,其中也有我自己调试时候的Log,大家可以自己调试下,看看不同参数的效果。昨天调参数搞到一点多,都在折腾这个函数。唉,一把辛酸泪。
身为一个相机,居然不能照相?真是太丢脸了!下面给我们的相机添加上照相的功能。照相核心代码就一句:mCamera.takePicture(null, null, jpeg);
可以看到takePicture方法有三个参数,分别是S

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

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

  • 手把手搭建自己的android环境,把手搭建android
  • Android 手把手带你玩转自定义相机
  • 手把手教你Android来去电通话自动录音的方法,android来去

相关文章

  • 2018-01-28Android Studio 错误解决办法
  • 2017-07-22android自定义圆角背景实现富文本标题展示
  • 2017-05-26Postgresql通过fdw_JDBC连接查询DB2\Oracle表
  • 2017-05-26Android 如何本地加载pdf文件,android加载pdf
  • 2017-05-26Install Battery Historian,batteryhistorian
  • 2017-05-26Android网络编程(四)从源码解析Volley
  • 2017-05-26Android 6.0 开发者对系统权限的使用与练习(Permissions Best Practices)
  • 2017-05-26Android获取本地相册图片、拍照获取图片,
  • 2017-05-26计算facebook sdk需要的key hashes,facebookhashes
  • 2017-05-26Android Studio: Error:Cannot locate factory for objects of type DefaultGradleConnector, as ConnectorServiceRegistry,locateregistry

文章分类

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

最近更新的内容

    • 我的android学习经历6,android学习经历6
    • ReactNative官方中文文档0.21,reactnative0.21
    • Xamarin Android 应用程序内图标上数字提示,xamarinandroid
    • achartengine/MPAndroidChart——图表实现之Java
    • android studio java.io.IOException:setDataSourse fail.,androidctsfail
    • 【项目篇】Android团队项目开发之统一代码规范
    • 安卓高级组件-----自动编辑文本框,安卓-----文本框
    • Android Studio 1.5.1 JNI 编程
    • android测试工具MonkeyRunner--google官网翻译
    • 关于JNI的使用方法,JNI使用方法

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

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