Android Camera的使用(一) 读书笔记
原文地址
https://blog.csdn.net/junzia/article/details/52301199
拍照步骤
1.添加权限
2.开启相机时check一下是否有摄像头
3.对预览大小、照片大小和对焦方式进行设置;对相机预览方向进行设置;
4.相机预览前,必须设置预览的承载;对预览View大小进行设置
5.相机预览时拍照,图像回调,对拍照的结果进行裁剪,使图片结果和预览结果相同,对前摄像头拍摄的结果还需要做对称变换。
相机的控制类CameraKitKat源码
public class CameraKitKat extends ACamera{ private Camera camera;
private SurfaceHolder holder;
private float displayScale; public CameraKitKat(SurfaceView surfaceView) {
super(surfaceView);
init();
} private void init(){
holder=displayView.getHolder();
}
//获得一个相机实例
@Override
public void open(int type){
//获取预览方向设置
int rotation=((WindowManager)displayView.getContext().getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay().getRotation();
//判断相机是否开启
if(!openCamera(type))return;
//修改相机设置
setParameters(camera,rotation);
//设置正确的预览方向
setDisplayOrientation(camera,rotation);
//设置预览的承载,如果没有这一步,相机无法开始预览
setPreviewDisplay(camera,holder);
//开启预览
camera.startPreview();
} @Override
public void close(){
camera.stopPreview();
camera.release();
} //调整SurfaceView的大小
private void resizeDisplayView(){
//获得相机实例的默认设置
Camera.Parameters parameters=camera.getParameters();
//将预览View的Size和Camera的PreviewSize设置相同
Camera.Size size=parameters.getPreviewSize();
//返回布局参数的引用
FrameLayout.LayoutParams p= (FrameLayout.LayoutParams) displayView.getLayoutParams();
float scale=size.width/(float)size.height;
displayScale=displayView.getHeight()/(float)displayView.getWidth();
if(scale>displayScale){
p.height= (int) (scale*displayView.getWidth());
p.width=displayView.getWidth();
}else{
p.width= (int) (displayView.getHeight()/scale);
p.height=displayView.getHeight();
}
Log.e("wuwang","-->"+size.width+"/"+size.height);
Log.e("wuwang","--<"+p.height+"/"+p.width);
displayView.setLayoutParams(p);
displayView.invalidate();
}
//获得当前设备的Camera个数,为0表示不支持摄像头
private boolean checkCameraId(int cameraId){
return cameraId>=0&&cameraId<Camera.getNumberOfCameras();
} //相机使用第一步,打开相机,获得相机实例
private boolean openCamera(int cameraId){
if(!checkCameraId(cameraId))return false;
camera=Camera.open(cameraId);
return true;
} //相机使用第二步,设置相机实例参数
//TODO :里面还存在问题,需要修改
private void setParameters(Camera camera,int rotation){
Camera.Parameters parameters=camera.getParameters(); //PreviewSize设置为设备支持的最高分辨率
final Camera.Size size=Collections.max(camera.getParameters().getSupportedPreviewSizes(),new Comparator<Camera.Size>() {
@Override
public int compare(Camera.Size lhs, Camera.Size rhs) {
return lhs.width*lhs.height-rhs.width*rhs.height;
}
});
parameters.setPreviewSize(size.width,size.height); //PictureSize设置为和预览大小最近的
Camera.Size picSize=Collections.max(parameters.getSupportedPictureSizes(), new Comparator<Camera.Size>() {
@Override
public int compare(Camera.Size lhs, Camera.Size rhs) {
return (int) (Math.sqrt(Math.pow(size.width-rhs.width,2)+Math.pow(size.height-rhs.height,2))-
Math.sqrt(Math.pow(size.width-lhs.width,2)+Math.pow(size.height-lhs.height,2)));
}
});
parameters.setPictureSize(picSize.width,picSize.height);
//如果相机支持自动聚焦,则设置相机自动聚焦,否则不设置
if(parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO)){
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
}
//设置颜色效果
// parameters.setColorEffect(Camera.Parameters.EFFECT_MONO);
camera.setParameters(parameters);
resizeDisplayView();
} //相机使用第三步,设置相机预览方向
private void setDisplayOrientation(Camera camera,int rotation){
if(rotation== Surface.ROTATION_0||rotation==Surface.ROTATION_180){
camera.setDisplayOrientation(90);
}else{
camera.setDisplayOrientation(0);
}
} //相机使用第四步,设置相机预览载体SurfaceHolder
private void setPreviewDisplay(Camera camera,SurfaceHolder holder){
try {
camera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
} @Override
public void measureSize(int width, int height) {
super.measureSize(width, height);
}
//拍照
@Override
public void takePicture() {
super.takePicture();
camera.takePicture(new Camera.ShutterCallback() {
@Override
//原始图像数据回调
public void onShutter() { }
}, new Camera.PictureCallback() {
@Override
//展示图像数据的回调
public void onPictureTaken(byte[] data, Camera camera) { }
}, new Camera.PictureCallback() {
@Override
//JPEG图像数据的回调
public void onPictureTaken(byte[] data, Camera camera) {
if(pictureCallback!=null){
pictureCallback.onPictureTaken(data,displayScale);
}
}
});
}
}
Android Camera的使用(一) 读书笔记的更多相关文章
- 《android开发艺术探索》读书笔记(七)--动画
接上篇<android开发艺术探索>读书笔记(六)--Drawable No1: 自定义动画:派生一种新动画只需要继承Animation这个抽象类,然后重写它的initialize和app ...
- 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化
第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...
- 《android开发艺术探索》读书笔记(十五)--Android性能优化
接上篇<android开发艺术探索>读书笔记(十四)--JNI和NDK编程 No1: 如果<include>制定了这个id属性,同时被包含的布局文件的根元素也制定了id属性,那 ...
- 《android开发艺术探索》读书笔记(十四)--JNI和NDK编程
接上篇<android开发艺术探索>读书笔记(十三)--综合技术 No1: Java JNI--Java Native Interface(java本地接口),它是为了方便java调用C. ...
- 《android开发艺术探索》读书笔记(十三)--综合技术
接上篇<android开发艺术探索>读书笔记(十二)--Bitmap的加载和Cache No1: 使用CrashHandler来获取应用的crash信息 No2: 在Android中单个d ...
- 《android开发艺术探索》读书笔记(十二)--Bitmap的加载和Cache
接上篇<android开发艺术探索>读书笔记(十一)--Android的线程和线程池 No1: 目前比较常用的缓存策略是LruCache和DiskLruCache,LruCache常被用作 ...
- 《android开发艺术探索》读书笔记(十一)--Android的线程和线程池
接上篇<android开发艺术探索>读书笔记(十)--Android的消息机制 No1: 在Android中可以扮演线程角色的有很多,比如AsyncTask.IntentService.H ...
- 《android开发艺术探索》读书笔记(十)--Android的消息机制
接上篇<android开发艺术探索>读书笔记(九)--四大组件 No1: 消息队列MessageQueue的内部存储结构并不是真正的队列,而是采用单链表的数据结构来存储消息列表,因为单链表 ...
- 《android开发艺术探索》读书笔记(九)--四大组件
接上篇<android开发艺术探索>读书笔记(八)--WindowManager No1: 四大组件除了BroadcastReceiver,其他三种组件都必须在AndroidManifes ...
- 《android开发艺术探索》读书笔记(八)--WindowManager
接上篇<android开发艺术探索>读书笔记(七)--动画 No1: Window是一个抽象类,它的具体实现是PhoneWindow.创建一个Window是很简单的事,只需要通过Windo ...
随机推荐
- VBA7种文档遍历法
Sub 在选定文档最后加入一句话() '遍历文件 Dim MyDialog As FileDialog On Error Resume Next Application.ScreenUpdating ...
- gradle windows上面安装配置
本文转载自: http://blog.csdn.net/u011546806/article/details/44806513 前提条件 安装jvm,并配置好了java环境变量 安装步骤 1.下载gr ...
- bzoj4576 [Usaco2016 Open]262144
题目大意: 给出n个数a[1..n],n<=262144,a[i]<=40,相邻且相同的数可以合并成一个并将值加1,问能获得的最大数是多少 用一个双向链表维护原数列,每个节点记录此节点对应 ...
- MySQL 高性能存储引擎:TokuDB初探
在安装MariaDB的时候了解到代替InnoDB的TokuDB,看简介非常的棒,这里对ToduDB做一个初步的整理,使用后再做更多的分享. 什么是TokuDB? 在MySQL最流行的支持全事务的引擎为 ...
- [C#]读文件
代码段来自 支付宝接口代码示例 /// <summary> /// 从文件读取公钥转公钥字符串 /// </summary> /// <param name=" ...
- SSH&SFTP服务分离+家目录锁定
Step 1 在root用户下创建维护账号的家目录,此处以创建userftp帐号的家目录为例. mkdir -p /chroot/home/user Step 2 在root用户根目录下执行以下命令设 ...
- 使用jenkins SVN MSBuil配置.net mvc网站进行持续集成
通过多次搭建Jenkins持续构建环境,终于对Jenkins有了进一步认识,在此把所学所得和大家分享一下,希望可以帮助大家快速掌握Jenkins的核心思想.看了很多文章,最终决定使用Jenkins.以 ...
- Selenium2+python自动化64-100(大结局)[已出书]
前言 小编曾经说过要写100篇关于selenium的博客文章,前面的64篇已经免费放到博客园供小伙伴们学习,后面的内容就不放出来了,高阶内容直接更新到百度阅读了. 一.百度阅读地址: 1.本书是在线阅 ...
- SQL中like的用法
操作符LIKE利用通配符把一个值与类似的值进行比较,通配符有两个: 1.百分号(%): 代表零个.一个或多个字符 2.下划线(_):代表一个数字或字符 下面的条件匹配任何以200开头的值 WHERE ...
- JSF多列预选择
<script type="text/javascript"> jQuery(document).ready(function () { preSelect(); }) ...