截屏相关

来源:互联网 发布:db2创建数据库 编辑:程序博客网 时间:2024/06/04 00:21

前段时间在做一个截屏分享的功能,所截取的内容包括一个surfaceView+MediaPlayer的视频,虽然最终实现了该功能,但是确实也走了很多弯路,当时本想总结一下的,但后来一直拖着没弄。最近又涉及到包含listView(要截取listView全部内容,包括屏幕以外的部分)截屏,弄完了就在此记录一下方便以后查看,免得过段时间忘了,又得到处找。

surfaceView截屏思路:

1.、先截取整个静态屏幕(screenBitmap)

2、获取当前的视频帧图片(vedioBitmap)

3、将获取帧图片vedioBitmap绘制在screenBitmap的黑色区域

 

首先截取静态屏幕,代码如下

<span style="white-space:pre"></span>public static Bitmap takeScreenShot(Activity activity) {// View是你需要截图的ViewView view = activity.getWindow().getDecorView();view.setDrawingCacheEnabled(true);view.buildDrawingCache();Bitmap b1 = view.getDrawingCache();// 获取状态栏高度Rect frame = new Rect();activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);int statusBarHeight = frame.top;System.out.println(statusBarHeight);// 获取屏幕长和高int width = activity.getWindowManager().getDefaultDisplay().getWidth();int height = activity.getWindowManager().getDefaultDisplay().getHeight();// 去掉标题栏// Bitmap b = Bitmap.createBitmap(b1, 0, 25, 320, 455);Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height- statusBarHeight);view.destroyDrawingCache();savePic(b, "/sdcard/screen_test.png");return b;}


这个方法截取静态屏幕是没问题的,但视频部分截出来的趋势黑色一片,根本不能看,主要是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和普通View有什么区别? (静态与动态的区别)

主要在于普通View内容draw之后,是静态的,我们不调用invalidate它就放在那, 拿到了Bitmap之后,我们可以获取到里面的内容。但是SurfaceView不同,我们无法拿到back buffer里面的bitmap。所以我们以往常用的截屏方案就不能够达到截下SurfaceView的效果。

 

获取当前的视频帧图片,代码如下:

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)private Bitmap createVideoThumbnail(String url, int width, int height) {    Bitmap bitmap = null;    MediaMetadataRetriever retriever = new MediaMetadataRetriever();    int kind = MediaStore.Video.Thumbnails.MINI_KIND;    try {      if (Build.VERSION.SDK_INT >= 14) {        retriever.setDataSource(url, new HashMap<String, String>());      } else {        retriever.setDataSource(url);      }      bitmap = retriever.getFrameAtTime();    } catch (IllegalArgumentException ex) {      // Assume this is a corrupt video file    } catch (RuntimeException ex) {      // Assume this is a corrupt video file.    } finally {      try {        retriever.release();      } catch (RuntimeException ex) {        // Ignore failures while cleaning up.      }    }    if (kind == Images.Thumbnails.MICRO_KIND && bitmap != null) {      bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,          ThumbnailUtils.OPTIONS_RECYCLE_INPUT);    }    return bitmap;  }
最后根据自己的逻辑(计算好位置、图片的宽高等等),以获取的静态屏幕图片为画布,将获取的帧图片绘制在黑色区域,即可。

查看的关于截屏的文章如下:

http://blog.csdn.net/bboyfeiyu/article/details/12712141

http://blog.csdn.net/hk_256/article/details/7306590

http://blog.csdn.net/yilip/article/details/7745584

http://blog.csdn.net/linyukun6422/article/details/43191333

http://huobengluantiao8.iteye.com/blog/1578117

http://www.tuicool.com/articles/uqmUFfY

http://blog.csdn.net/woshinia/article/details/11520403



listView截屏思路(gridView类似):

              listView的截屏就比较简单了,主要是把每个item的view转换为bitmap,然后注意绘制在适当的位置就ok了。参考http://www.darcye.com/article/84263064


<span style="white-space:pre"></span>public static Bitmap createBitmap(ListView listView, Context context) {int width, rootHeight = 0;int yPos = 0;int listItemNum;List<View> childViews = null;width = ViewUtil.getScreenWidth(context);// 宽度等于屏幕宽ListAdapter listAdapter = listView.getAdapter();listItemNum = listAdapter.getCount();childViews = new ArrayList<View>(listItemNum);View itemView;// 计算整体高度:for (int pos = 0; pos < listItemNum; ++pos) {itemView = listAdapter.getView(pos, null, listView);// measure过程itemView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));childViews.add(itemView);rootHeight += itemView.getMeasuredHeight();}Bitmap bitmap = Bitmap.createBitmap(width, rootHeight, Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);Bitmap itemBitmap;int childHeight;// 把每个ItemView生成图片,并画到背景画布上for (int pos = 0; pos < childViews.size(); ++pos) {itemView = childViews.get(pos);childHeight = itemView.getMeasuredHeight();itemBitmap = viewToBitmap(itemView, width, childHeight);if (itemBitmap != null) {canvas.drawBitmap(itemBitmap, 0, yPos, null);}yPos = childHeight + yPos;}canvas.save(Canvas.ALL_SAVE_FLAG);canvas.restore();return bitmap;}

<span style="white-space:pre"></span>private static Bitmap viewToBitmap(View view, int viewWidth, int viewHeight) {view.layout(0, 0, viewWidth, viewHeight);view.buildDrawingCache();Bitmap bitmap = view.getDrawingCache();return bitmap;}



</pre><pre>
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孕13周血糖偏高怎么办 餐后血糖高14点怎么办 餐后血糖20多怎么办 空腹血糖6.6饭后9.2怎么办 键盘shift键失效了怎么办 灵异附身夫妻不合怎么办 鞋子买大了半码怎么办 鞋子买小了半码怎么办 黑布鞋鞋面白了怎么办 黑布鞋不黑了怎么办 黑布鞋退白了怎么办 老北京布鞋款式太少怎么办 老人输液抽搐后昏迷怎么办 头七家里有狗怎么办 股票退市股民的钱怎么办 美国股票退市股民怎么办 百度云字幕和视频不同步怎么办 百度云加载字幕有延迟怎么办 很难适应新环境怎么办 蜘蛛丝碰到嘴唇上起包有毒怎么办? 电瓶车在路上爆胎了怎么办 嘴被虫子咬肿了怎么办 高铁管家购票失败怎么办 高铁车厢空调冷怎么办 高铁票过了时间怎么办 网购火车票丢了怎么办 改签没有票了怎么办 火车票取了没赶上车怎么办 上车后车票丢了怎么办 晒了吗任务过期怎么办 坐火车买了站票怎么办 坐火车忘记带票怎么办 距离二本线差几分怎么办 行李包落火车候车厅怎么办 高铁票买错地点怎么办 高铁票买错日期怎么办 票买错时间了怎么办 上高铁了票丢了怎么办 上车前高铁票丢了怎么办 高铁安检没收的东西怎么办 高铁安检员老了怎么办