当前位置:   article > 正文

Android 任意View转为bitmap图片_imageview转化为bitmap

imageview转化为bitmap

在开发的过程中有时会碰到这样的需求,把一个activity或者一个view变成图片分享出去。从网上收集了一些资料之后经过整理现在分享出来,教大家实现activity,scrollview,listview,recycleview,画中画以及在后台把layout生成图片的方法。如有侵权的地方,请及时告诉我改正,谢谢。

代码在这里 https://github.com/iotxc/ScreenShootDemo

在贴方法之前我要提醒大家注意一点,view中有图片的,如果是本地图片那么网上的代码你拿过来直接用就行了,如果是根据url加载的你要注意了,直接写Glide.with(this).load(url).into(imageview);你得到的将会是一片空白,要使用simpleTarget的回调加载图片才行

 

  1. Glide.with(this)
  2. .load(url)
  3. .asBitmap()
  4. .into(new SimpleTarget<Bitmap>() {
  5. @Override
  6. public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
  7. imageview.setImageBitmap(resource);
  8. }
  9. });

具体是为什么我还不清楚。

 

 

screenshoot.gif

 

我也不知道视频为什么会这么模糊,凑合看一下吧= =,有知道怎么做的清晰点的请留言告诉我

1. activity截图

 

  1. /**
  2. * 获取指定Activity的截屏
  3. */
  4. public static Bitmap activityScreenShot(Activity activity) {
  5. // View是你需要截图的View
  6. View view = activity.getWindow().getDecorView();
  7. view.setDrawingCacheEnabled(true);
  8. view.buildDrawingCache();
  9. Bitmap bitmap = view.getDrawingCache();
  10. // 获取状态栏高度
  11. Rect frame = new Rect();
  12. activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
  13. int statusBarHeight = frame.top;
  14. // 获取屏幕长和高
  15. int width = activity.getWindowManager().getDefaultDisplay().getWidth();
  16. int height = activity.getWindowManager().getDefaultDisplay().getHeight();
  17. // 去掉标题栏
  18. Bitmap b = Bitmap.createBitmap(bitmap, 0, statusBarHeight, width, height - statusBarHeight);
  19. view.destroyDrawingCache();
  20. return b;
  21. }

2. scrollview截图
因为ScrollView只有一个childView,虽然没有全部显示在界面上,但是已经全部渲染绘制,因此可以直接调用scrollView.draw(canvas)来完成截图

 

  1. /**
  2. * 获取scrollview的截屏
  3. */
  4. public static Bitmap scrollViewScreenShot(ScrollView scrollView) {
  5. int h = 0;
  6. Bitmap bitmap = null;
  7. for (int i = 0; i < scrollView.getChildCount(); i++) {
  8. h += scrollView.getChildAt(i).getHeight();
  9. scrollView.getChildAt(i).setBackgroundColor(Color.parseColor("#ffffff"));
  10. }
  11. bitmap = Bitmap.createBitmap(scrollView.getWidth(), h, Bitmap.Config.RGB_565);
  12. final Canvas canvas = new Canvas(bitmap);
  13. scrollView.draw(canvas);
  14. return bitmap;
  15. }

3. listview截图
因为listview布局复用的问题并且只能绘制在屏幕上显示的ItemView,所以我们需要把它的item放到一个view的集合里最后通过拼接来完成整图的效果。但是当Item足够多的时候,肯定会发生oom的所以记得在获得bitmap之后对其进行压缩处理。

 

  1. /**
  2. * 获取listview的截屏
  3. * @param listview
  4. * @return
  5. */
  6. public static Bitmap shotListView(ListView listview) {
  7. ListAdapter adapter = listview.getAdapter();
  8. int itemscount = adapter.getCount();
  9. int allitemsheight = 0;
  10. List<Bitmap> bmps = new ArrayList<Bitmap>();
  11. //循环对listview的item进行截图, 最后拼接在一起
  12. for (int i = 0; i < itemscount; i++) {
  13. View childView = adapter.getView(i, null, listview);
  14. childView.measure(
  15. View.MeasureSpec.makeMeasureSpec(listview.getWidth(), View.MeasureSpec.EXACTLY),
  16. View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
  17. childView.layout(0, 0, childView.getMeasuredWidth(), childView.getMeasuredHeight());
  18. childView.setDrawingCacheEnabled(true);
  19. childView.buildDrawingCache();
  20. bmps.add(childView.getDrawingCache());
  21. allitemsheight += childView.getMeasuredHeight();
  22. //这里可以把listview中单独的item进行保存
  23. // viewSaveToImage(childView.getDrawingCache());
  24. }
  25. int w = listview.getMeasuredWidth();
  26. Bitmap bigbitmap = Bitmap.createBitmap(w, allitemsheight, Bitmap.Config.ARGB_8888);
  27. Canvas bigcanvas = new Canvas(bigbitmap);
  28. Paint paint = new Paint();
  29. int iHeight = 0;
  30. for (int i = 0; i < bmps.size(); i++) {
  31. Bitmap bmp = bmps.get(i);
  32. bigcanvas.drawBitmap(bmp, 0, iHeight, paint);
  33. iHeight += bmp.getHeight();
  34. bmp.recycle();
  35. bmp = null;
  36. }
  37. return bigbitmap;
  38. }

4. recycleview截图
recycleview和listView使用相同的方案

 

  1. /**
  2. * recycleview截图
  3. * @param view
  4. * @return
  5. */
  6. public static Bitmap shotRecyclerView(RecyclerView view) {
  7. RecyclerView.Adapter adapter = view.getAdapter();
  8. Bitmap bigBitmap = null;
  9. if (adapter != null) {
  10. int size = adapter.getItemCount();
  11. int height = 0;
  12. Paint paint = new Paint();
  13. int iHeight = 0;
  14. final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
  15. // Use 1/8th of the available memory for this memory cache.
  16. final int cacheSize = maxMemory / 8;
  17. LruCache<String, Bitmap> bitmaCache = new LruCache<>(cacheSize);
  18. for (int i = 0; i < size; i++) {
  19. RecyclerView.ViewHolder holder = adapter.createViewHolder(view, adapter.getItemViewType(i));
  20. adapter.onBindViewHolder(holder, i);
  21. holder.itemView.measure(
  22. View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY),
  23. View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
  24. holder.itemView.layout(0, 0, holder.itemView.getMeasuredWidth(),
  25. holder.itemView.getMeasuredHeight());
  26. holder.itemView.setDrawingCacheEnabled(true);
  27. holder.itemView.buildDrawingCache();
  28. Bitmap drawingCache = holder.itemView.getDrawingCache();
  29. if (drawingCache != null) {
  30. bitmaCache.put(String.valueOf(i), drawingCache);
  31. }
  32. height += holder.itemView.getMeasuredHeight();
  33. }
  34. bigBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), height, Bitmap.Config.ARGB_8888);
  35. Canvas bigCanvas = new Canvas(bigBitmap);
  36. Drawable lBackground = view.getBackground();
  37. if (lBackground instanceof ColorDrawable) {
  38. ColorDrawable lColorDrawable = (ColorDrawable) lBackground;
  39. int lColor = lColorDrawable.getColor();
  40. bigCanvas.drawColor(lColor);
  41. }
  42. for (int i = 0; i < size; i++) {
  43. Bitmap bitmap = bitmaCache.get(String.valueOf(i));
  44. bigCanvas.drawBitmap(bitmap, 0f, iHeight, paint);
  45. iHeight += bitmap.getHeight();
  46. bitmap.recycle();
  47. }
  48. }
  49. return bigBitmap;
  50. }

5. 任意View转bitmap

 

  1. /**
  2. * view转bitmap
  3. */
  4. public Bitmap viewConversionBitmap(View v) {
  5. int w = v.getWidth();
  6. int h = v.getHeight();
  7. Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
  8. Canvas c = new Canvas(bmp);
  9. c.drawColor(Color.WHITE);
  10. /** 如果不设置canvas画布为白色,则生成透明 */
  11. v.layout(0, 0, w, h);
  12. v.draw(c);
  13. return bmp;
  14. }

注意:这里的view只能是已经显示在界面上的,那没显示在界面上的怎么处理?往下看
此方法也是后台生成view的方法:

 

  1. /**
  2. * 计算view的大小
  3. */
  4. public void measureSize(Activity activity, String url) {
  5. //将布局转化成view对象
  6. View viewBitmap = LayoutInflater.from(activity).inflate(R.layout.background_layout, null);
  7. WindowManager manager = activity.getWindowManager();
  8. DisplayMetrics outMetrics = new DisplayMetrics();
  9. manager.getDefaultDisplay().getMetrics(outMetrics);
  10. int width = outMetrics.widthPixels;
  11. int height = outMetrics.heightPixels;
  12. //然后View和其内部的子View都具有了实际大小,也就是完成了布局,相当与添加到了界面上。接着就可以创建位图并在上面绘制了:
  13. layoutView(viewBitmap, width, height, url, activity);
  14. }
  15. /**
  16. * 填充布局内容
  17. */
  18. public void layoutView(final View viewBitmap, int width, int height, String url, Activity activity) {
  19. // 整个View的大小 参数是左上角 和右下角的坐标
  20. viewBitmap.layout(0, 0, width, height);
  21. int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
  22. int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.AT_MOST);
  23. viewBitmap.measure(measuredWidth, measuredHeight);
  24. viewBitmap.layout(0, 0, viewBitmap.getMeasuredWidth(), viewBitmap.getMeasuredHeight());
  25. TextView tv = viewBitmap.findViewById(R.id.tv_background);
  26. tv.setText("这是后台生成图片的标题");
  27. final ImageView imageView = viewBitmap.findViewById(R.id.iv_background);
  28. //注意加载网络图片时一定要用SimpleTarget回调
  29. Glide.with(activity).load(url).asBitmap().into(new SimpleTarget<Bitmap>() {
  30. @Override
  31. public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
  32. imageView.setImageBitmap(resource);
  33. viewSaveToImage(viewBitmap);
  34. }
  35. });
  36. }
  37. /**
  38. * 把view转成图片
  39. * @param view
  40. */
  41. private void viewSaveToImage(View view) {
  42. view.setDrawingCacheEnabled(true);
  43. view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
  44. view.setDrawingCacheBackgroundColor(Color.WHITE);
  45. // 把一个View转换成图片
  46. Bitmap cachebmp = viewConversionBitmap(view);
  47. if (mBitmapDoneListener != null){
  48. mBitmapDoneListener.bitmapDone(cachebmp);
  49. }
  50. view.destroyDrawingCache();
  51. }

6. 圆角画中画

 

  1. /**
  2. * view转bitmap
  3. */
  4. public Bitmap viewConversionBitmap(View v) {
  5. int w = v.getWidth();
  6. int h = v.getHeight();
  7. Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
  8. Canvas c = new Canvas(bmp);
  9. c.drawColor(Color.WHITE);
  10. /** 如果不设置canvas画布为白色,则生成透明 */
  11. v.layout(0, 0, w, h);
  12. v.draw(c);
  13. return bmp;
  14. }
  15. /**
  16. * 把上面获得的bitmap传进来就可以得到圆角的bitmap了
  17. */
  18. public void bitmapInBitmap(Bitmap bitmap, ImageView imageView) {
  19. Bitmap tempBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
  20. Canvas canvas = new Canvas(tempBitmap);
  21. //图像上画矩形
  22. Paint paint = new Paint();
  23. paint.setColor(Color.TRANSPARENT);
  24. paint.setStyle(Paint.Style.STROKE);//不填充
  25. paint.setStrokeWidth(10); //线的宽度
  26. canvas.drawRect(10, 20, 100, 100, paint);
  27. imageView.setImageBitmap(tempBitmap);
  28. //画中画
  29. Paint photoPaint = new Paint(); // 建立画笔
  30. photoPaint.setDither(true); // 获取跟清晰的图像采样
  31. photoPaint.setFilterBitmap(true);// 过滤一些
  32. Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());// 创建一个指定的新矩形的坐标
  33. Rect dst = new Rect(0, 0, 300, 350);// 创建一个指定的新矩形的坐标
  34. canvas.drawBitmap(tempBitmap, src, dst, photoPaint);// 将photo 缩放或则扩大到
  35. imageView.setImageBitmap(getRoundedCornerBitmap(tempBitmap));
  36. }
  37. /**
  38. * 生成圆角图片
  39. */
  40. public Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
  41. try {
  42. Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
  43. bitmap.getHeight(), Bitmap.Config.ARGB_8888);
  44. Canvas canvas = new Canvas(output);
  45. final Paint paint = new Paint();
  46. final Rect rect = new Rect(0, 0, bitmap.getWidth(),
  47. bitmap.getHeight());
  48. final RectF rectF = new RectF(new Rect(0, 0, bitmap.getWidth(),
  49. bitmap.getHeight()));
  50. //设置圆角大小
  51. final float roundPx = 30;
  52. paint.setAntiAlias(true);
  53. canvas.drawARGB(0, 0, 0, 0);
  54. paint.setColor(Color.BLACK);
  55. canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
  56. paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
  57. final Rect src = new Rect(0, 0, bitmap.getWidth(),
  58. bitmap.getHeight());
  59. canvas.drawBitmap(bitmap, src, rect, paint);
  60. return output;
  61. } catch (Exception e) {
  62. return bitmap;
  63. }
  64. }

以上就是所有的view转bitmap操作,得到bitmap之后你们就可以为所欲为了- -

再次提醒一下:加载网络图片要使用simpleTarget回调,直接加载得到的是一片空白,切记!!!
目前博主只试过glide一种图片框架,其他框架请自行试验




原文链接:https://www.jianshu.com/p/3d03c66cf169

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/262153
推荐阅读
相关标签
  

闽ICP备14008679号