Android自定义拍照小米手机拍照照片模糊的问题

news/2025/1/16 7:47:59/

原文地址      

昨天同事跟我说了一个bug,让我整了一天,从昨天下午这个时间到今天下午这个时间,哎... 大家都懂的

首先我来说一个bug,我用surfaceView来实现自定义拍照的功能,先来张在genymotion运行的截图

  


















大体就是这个样子,相机上面附上一张图片加上几个按钮,来实现拍照的基本需求,但是拍完照片的时候在小米4手机上拍完之后展示的照片非常模糊,就像是被压缩的很厉害,于是就开始来解决这个bug

   下面我做一个小的Demo,来说一下解决这个bug走的弯路,记录一下这里的一些功能的实现,以便以后遇到类似的需求直接拿来用,直奔主题

这个功能的实现我是基于EasyCamera--更简单更灵活的相机应用编写 这篇博客来实现我的功能的,谢谢这个博主

EasyCamera.PictureCallback mPictureCallback = new EasyCamera.PictureCallback(){
  1. @Override
  2. public void onPictureTaken(byte[] data, EasyCamera.CameraActions actions)
<span style="white-space:pre">	</span>}
};

点击拍照按钮执行这个方法,得到onPictureTaken()这个方法的回调,我们想要得到的数据就存在第一个参数这个数组中,由于三星Note 3手机拍的照片正常,所以我就把这个得到的大小和小米4手机拍的照片得到的大小进行比较,结果我发现这个两个大小差不多,说明小米4系统没有进行特别大的压缩,这里我走的弯路,我在这里卡住了,我google了网上遇到类似的问题,其中有一个的做法是他先是把拍的照片直接存到本地,然后在需要展示照片的时候,获取本地保存的照片,进行展示,但是我也尝试这种做法结果可想而知,然并卵!为什么呢?想必一猜就知道,人家遇到的情况跟我不一样,先说说他的情况,他是调用系统的照相机,拍完照之后把数据用Intent返回到上一个页面,由于图片太大,所以系统进行了压缩Android相机和本地相册获取图片显示并保存到SD卡 这是那篇博文,当然这种情况的这种做法还是很合理的,拍完之后接着保存到本地,需要的时候从本地读取,这样的话保证图片的清晰度和分辨率,自行再进行压缩. 但是我需求不是这样的,我得到了data保存起来,展示的时候接着读取,都是在一个页面中进行的,这不是典型的脱掉裤子放屁,多此一举嘛,当时也是没有多想,死马当活马医!这是我的第一次个弯路然后我就想,既然三星手机得到data和小米4手机得到的data大小差不多,说明不能onPictureTaken()这个方法上面找,得往下面找这个问题的原因

  1. <span style="font-size:18px;">/**
  2. * 图片旋转
  3. *
  4. * @param b
  5. * @return
  6. */
  7. private Bitmap imageRotate(byte[] b, int angle) {
  8. Bitmap <span style="color:#ff6666;">bitmap</span> = BitmapFactory.decodeByteArray(b, 0, b.length);
  9. Matrix matrix = new Matrix();
  10. if (cameraPosition == 1) {
  11. matrix.postScale(-1, 1); // 镜像水平翻转
  12. }
  13. matrix.postRotate(angle);
  14. bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
  15. // bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
  16. return bitmap;
  17. }</span>


 

如果对得到的照片不进行处理直接展示的话,会展示出一个镜像旋转的图片,这个原因不太了解,有了解的童鞋可以说一下,所以我就进行镜像水平翻转,最后得到一个bitmap进行展示,我就使劲看这个方法有没有牵扯到压缩,是不是因为我的这块代码导致我图片变得不清楚,分辨率特别低,就在这时候我发现了原因,在一次调试的时候我发现这个bitmap(上面代码块红色)的height和width特别小,比用系统相机小很多

可以看一下我debug的结果,这就是我上面代码块红色的bitmap的width和height的值,这么小,我靠!原因终于找到了,分辨率这么小,但是我让图片强制拉大展示,当然看到很模糊了!

现在就是就是怎么解决这个bug了,既然原因找到了,那么解决就相对简单了.但是,这个设置宽高我也是费了很大功夫,首先我该对谁进行宽高的处理bitmap or camera ? 我先强制设置了得到的bitmap的宽高,让他的宽高跟手机分辨率一样,但是然并卵,既然bitmap的宽高设置没有用,那么我就继续往上找原因,我看到了这个EasyCamera,可不可以在这个地方做文章?我就google了一下,可不可以在拍照的时候进行尺寸的设置,结果果然有这样的方法

  1. // Parameters parameters = mEasyCamera.getParameters();// 获取相机参数集
  2. // List<Size> SupportedPreviewSizes =
  3. // parameters.getSupportedPreviewSizes();// 获取支持预览照片的尺寸
  4. // Size previewSize = SupportedPreviewSizes.get(0);// 从List取出Size
  5. // parameters.setPreviewSize(previewSize.width, previewSize.height);//
  6. // 设置预览照片的大小
  7. // List<Size> supportedPictureSizes =
  8. // parameters.getSupportedPictureSizes();// 获取支持保存图片的尺寸
  9. // Size pictureSize = supportedPictureSizes.get(0);// 从List取出Size
  10. // parameters.setPictureSize(previewSize.width, previewSize.height);//
  11. // 设置照片的大小
  12. // mEasyCamera.setParameters(parameters);


这一堆代码,果然,可以设置,parameters.getSupportedPreviewSizes()和parameters.getSupportedPictureSizes()返回的都是一个list 存放的Size类型的数据,就是它支持的宽高的尺寸,结果这个list的大小真不小,而且不同的手机这个list的大小也是不一样的,这样的话我就有思路了,我把拍照时的尺寸设置成屏幕的分辨率就可以了啊,但是问题又出来了,有个问题我不确定,这个list里面一定有本手机屏幕的分辨率吗?我估计应该有,但是不确定,所以这个地方我要做点特殊处理.首先,我遍历这个list找到跟屏幕分辨率相等的那个size然后返回这个下标,如果没有这个分辨率的话,我就取出这个list中间的一个size的下标进行返回(因为我发现这个list里面的size它是由从大到小的顺序进行排序的,所以我选择了一个大胆的想法,选取中间一个size)


 
  1. <span style="font-size:18px;">/**
  2. * 获取拍照之后的尺寸
  3. */
  4. private int getPictureSize(List<Size> sizes) {
  5. // 屏幕的宽度
  6. int screenWidth = MyApplication.getMYIntance().widthPixels;
  7. int index = -1;
  8. for (int i = 0; i < sizes.size(); i++) {
  9. if (Math.abs(screenWidth - sizes.get(i).width) == 0) {
  10. index = i;
  11. break;
  12. }
  13. }
  14. // 当未找到与手机分辨率相等的数值,取列表中间的分辨率
  15. if (index == -1) {
  16. index = sizes.size() / 2;
  17. }
  18. return index;
  19. }</span>

这是代码,设置了EasyCamera的parameter,但是问题又来了,这段代码写在何地?刚开始的时候,我把这段代码写在了SurfaceHolder的surfaceCreated和surfaceChanged方法中,这样,进入这个页面第一次拍照,得到的照片很清晰,但是当我点击取消,再次拍照的时候图片就变模糊了,后来我把这段代码写在了点击拍照的那个按钮的点击事件上就OK了.

到此为止,这个bug就算完成了,后面对图片的压缩等一系列的操作就根据自己的需求进行了由于时间很紧,写得挺仓促,博客的格式基本没有,大家凑合着看吧,我主要是想把我这近一天的bug解决经历分享一下,而并不是给出这个bug的解决方案,主要是说一下思路和我当时遇到的坑和走的弯路,思路最重要!

当然还有几处不明白的地方,比如图片为什么自动翻转了,这个还需要继续努力寻找原因


源码下载      代码只是简单的功能实现




http://www.ppmy.cn/news/745864.html

相关文章

用智能手机拍的模糊照片怎么办?学会这个技巧让它变得清晰

智能手机的相机功能越来越强大&#xff0c;但有时候我们还是会拍出一些模糊的照片。这可能是因为手抖或者光线不足等原因导致的。但不要担心&#xff0c;有一些简单的技巧可以帮助您将模糊的照片变得更加清晰。 1.稳定手机 拍摄清晰照片的第一步是确保相机保持稳定。拍照时最…

Linux:Vim文本编辑器及其应用详解

Vim 的安装 众多 Linux 发行版系统&#xff0c;通常都已经默认安装好了 vi 或 Vim 文本编辑器&#xff0c;Centos 也不例外&#xff0c;该系统就默认安装有 vi 文本编辑器&#xff0c;但建议大家使用 Vim。 如果在命令行模式下输入“vim”&#xff0c;输出结果为“Command no…

微信公众号本地开发调试 - 无公网IP,内网穿透

文章目录 前言1. 配置本地服务器2. 内网穿透2.1 下载安装cpolar内网穿透2.2 创建隧道 3. 测试公网访问4. 固定域名4.1 保留一个二级子域名4.2 配置二级子域名 5. 使用固定二级子域名进行微信开发 前言 在微信公众号开发中&#xff0c;微信要求开发者需要拥有自己的服务器资源来…

海康大华网络摄像机搜索工具

在配置网络摄像机时&#xff0c;需要一个工具可以搜索到在线的网络摄像机&#xff0c;海康和大华各有一套&#xff0c;海康的叫SADPTool&#xff0c;大华的叫SmartPSS。为什么可以搜索到连接到路由器上的网络摄像机&#xff0c;其原理是利用多播&#xff0c;如果网络摄像机的ip…

买路由不再怕偷工减料 专业测评工具懂路由APP上线

中新网1月26日电 近日&#xff0c;国内首款专业的路由器测评工具“懂路由”正式上线。 现在无线网络已经成为日常生活的一部分&#xff0c;从手机、笔记本电脑到智能音箱、智能摄像机等智能硬件的使用都离不开WiFi&#xff0c;网购、游戏、刷剧和社交无不与无线WiFi有着千丝万…

【资讯】2017年最好的25大发明,你最钟爱哪个?

引言《时代周刊》每年都会评出一份有趣的发明榜单&#xff0c;悉数一年间世界范围内的重大发明。今年的榜单出来后&#xff0c;「得到」作者马徐骏抢先进行了解读。带你一起看看&#xff0c;2017年有哪些发明正在悄然改变我们的生活。1. 阿迪达斯的4D跑鞋——Futurecraft这款鞋…

(一)海康威视、大华、宇视、广州视鹰 摄像机,支持SDK二次开发

一、简介 1、我想找一款尽可能小的网络摄像机&#xff0c;越小越好&#xff0c;并且支持SDK二次开发的。 2、我要实现的功能是&#xff1a;通俗地说&#xff0c;我要把监控的视频画面&#xff0c;作为一部份&#xff0c;放到我的软件上显示。在我软件的软件&#xff0c;点击打…

IoT入口之争:创米在智能摄像机创造的2000万+背后的秘密

智能音箱大战余热尚在&#xff0c;智能摄像机的战场就已经开始排兵布阵&#xff0c;蠢蠢欲动。攻防之势&#xff0c;跃然纸面。 其实&#xff0c;摄像机产品由来已久&#xff0c;智能摄像机市场也走过了四个年头&#xff0c;但是由于前几年巨头厂商并没有真正发力&#xff0c;…