Android应用截图和SurfaceView截图问题(学生PAD抽奖系统)
来源:互联网 发布:js兄弟节点 编辑:程序博客网 时间:2024/06/05 11:13
问题描述
要将背景进行模糊后并进行一系列的动画效果,这个处理流程大致为:
① 获取中奖后的最后一帧背景图
② 将背景图进行缩放、模糊处理
③ 将处理后的背景图设置给中奖界面,并进行后续动画效果。
思路很简单,但是在实际开发中就会出现了不少问题,主要难点还是在于第一步: 如何获取中奖后最后一帧的背景图片。可能大部分同学都觉得系统提供了截屏的接口,直接调用就可以获取到了或者从Window的DrawbleCache中直接获取。 那么我们可以来看一下,通过这些方式我们获取的背景图片会是什么样的,见下图1-2:
是不是很奇怪,为什么会有黑屏,是不是我截屏的方式错误了? 那么出现这个原因我们得先大致描述一下该界面搭建所采用的技术。
抽奖系统界面搭建方案说明
① 由于策划事先声明后期可能存在多种方式的抽奖,所以我采用了Activity+(ViewPager+Fragment)的方式搭建了这个界面结构。
② 抽奖的主界面,考虑到界面刷新的频率较高,有玩过的同学会知道,该抽奖的效果较多,所以采用了具备双缓冲特性的SurfaceView来完成这个矩形抽奖界面。
③ 整个外围的界面搭建主要就是采用上述描述的技术。具体内部实现比如这个一个个选项框如何绘制成一个矩形(后续会有博文进行说明)
截屏黑屏原因分析
通过上述描述,对SurfaceView有了解的同学应该会知道,黑屏的原因就是在于SurfaceView的实现原理:
SurfaceView通常有两个缓冲区(buffer), 一个front buffer,一个back buffer。而back buffer就是Canvas对应的bitmap。每当frong buffer显示时,back buffer就迅速的绘制,然后front buffer迅速将当前的back buffer显示给用户。由于速度十分快,所以便形成了动画效果。View是在UI的主线程中更新画面,而SurfaceView是在一个新线程中更新画面。这就需要你new一个新线程,在新线程里面进行绘画的工作。 SurfaceView通过SurfaceHolder对象将back buffer画好的内容更新到front buffer。 这也就是为什么我们在使用SurfaceView时需要将canvas进行锁定。 这里就不具体描述SurfaceView的用法,不太了解的同学可以自行去google一下。
那么说了这么多,SurfaceView和普通View有什么区别? (静态与动态的区别)
主要在于普通View内容draw之后,是静态的,我们不调用invalidate它就放在那, 拿到了Bitmap之后,我们可以获取到里面的内容。但是SurfaceView不同,我们无法拿到back buffer里面的bitmap。所以我们以往常用的截屏方案就不能够达到截下SurfaceView的效果。
黑屏解决方案
普通截屏代码如下:
// View是你需要截图的View View view = activity.getWindow().getDecorView(); view.setDrawingCacheEnabled(true); // 开启cache view.buildDrawingCache(); Bitmap b1 = view.getDrawingCache();// 获取cache的图片 通过以上代码我们就可以获取到静态界面的背景图片
SurfaceView的截屏代码如下:
分析:由于SurfaceHolder.lockCanvas()返回的Canvas是用来更新SurfaceView的,所以我们只需要自己定义个画板Canvas将当前SurfaceView绘制的内容绘制到我们自己的画板上,那么我们之前提供的Bitmap就绘制上了当前SurfaceView back buffer里面的内容。Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); draw(canvas); // SurfaceHolder.lockCanvas()返回的Canvas 绘制什么内容,我们定义的也绘制一遍。
绘制结束后我们传入的bitmap就已经有了我们需要的内容
普通View和SurfaceView图片组合问题
Rect r = new Rect(); vLotteryRectView.getGlobalVisibleRect(r); fuzzyBgBitmap = vLotteryRectView.takeScreenShot(r, mActivity); // 模糊掉的背景图
主要是通过vLotteryRectView.getGlobalVisibleRect(r); 方法来获取当前vLotteryRectView (SurfaceView) 的Rect值。 通过Rect我们就可以非常完美的获取到抽奖界面距离屏幕的上下左右数值。
进而将SurfaceView 完美的绘制在普通View黑屏的地方。获取到组合的背景图片之后,我们就可以将该图片进行相应的图片处理。来达到我们想要的效果
实际项目效果图
通过上述方案最终达到的效果如下图1-4所示:
PS: 图片中背景有点怪其实是因为缩放的原因,可以采用很多方案进行解决,这里就不做处理了,希望本篇文章可以帮助到需要帮助的朋友。
- Android应用截图和SurfaceView截图问题(学生PAD抽奖系统)
- Android应用截图和SurfaceView截图问题总结
- Android应用截图和SurfaceView截图问题总结
- android surfaceview截图 系统截图
- Android中截图(surfaceView)
- 【拍照截图】Android 系统拍照和截图
- android应用内截图问题
- 关于SurfaceView的截图问题
- surfaceview截图
- Android MediaProjection截屏与录屏(surfaceview截图)
- 游戏内截图,surfaceView截图
- android 应用demo截图
- Android应用内截图
- Android应用截图方法
- ANDROID应用内截图
- Android 系统截图
- Android系统截图分享
- 学生信息管理系统[有软件截图]
- 判断一个单向链表中是否有环
- 什么是C#编程语言明明白白学C#
- RFC中关于IPv6 DNS的介绍
- cocos2d-x 3.2 之 三消类游戏——万圣大作战 (第三篇)
- leetcode30 Substring with Concatenation of All Word
- Android应用截图和SurfaceView截图问题(学生PAD抽奖系统)
- mysql5.1中utf8编码下一个汉字占用一个char的疑惑
- C#获取 URL参数
- 10大算法之kmeans算法学习
- STM32重映射简介
- ubuntu 13.10之后的系统启动出现Grub rescue的修复方法
- C语言——设计printf调试宏
- RTSP协议详解
- MAC下安装wget