1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Android 任意View转为bitmap图片

Android 任意View转为bitmap图片

时间:2019-10-25 06:34:47

相关推荐

Android 任意View转为bitmap图片

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

代码在这里 /iotxc/ScreenShootDemo

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

Glide.with(this).load(url).asBitmap().into(new SimpleTarget<Bitmap>() {@Overridepublic void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {imageview.setImageBitmap(resource);}});

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

screenshoot.gif

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

1. activity截图

/*** 获取指定Activity的截屏*/public static Bitmap activityScreenShot(Activity activity) {// View是你需要截图的ViewView view = activity.getWindow().getDecorView();view.setDrawingCacheEnabled(true);view.buildDrawingCache();Bitmap bitmap = view.getDrawingCache();// 获取状态栏高度Rect frame = new Rect();activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);int statusBarHeight = frame.top;// 获取屏幕长和高int width = activity.getWindowManager().getDefaultDisplay().getWidth();int height = activity.getWindowManager().getDefaultDisplay().getHeight();// 去掉标题栏Bitmap b = Bitmap.createBitmap(bitmap, 0, statusBarHeight, width, height - statusBarHeight);view.destroyDrawingCache();return b;}

2. scrollview截图

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

/*** 获取scrollview的截屏*/public static Bitmap scrollViewScreenShot(ScrollView scrollView) {int h = 0;Bitmap bitmap = null;for (int i = 0; i < scrollView.getChildCount(); i++) {h += scrollView.getChildAt(i).getHeight();scrollView.getChildAt(i).setBackgroundColor(Color.parseColor("#ffffff"));}bitmap = Bitmap.createBitmap(scrollView.getWidth(), h, Bitmap.Config.RGB_565);final Canvas canvas = new Canvas(bitmap);scrollView.draw(canvas);return bitmap;}

3. listview截图

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

/*** 获取listview的截屏* @param listview* @return*/public static Bitmap shotListView(ListView listview) {ListAdapter adapter = listview.getAdapter();int itemscount = adapter.getCount();int allitemsheight = 0;List<Bitmap> bmps = new ArrayList<Bitmap>();//循环对listview的item进行截图, 最后拼接在一起for (int i = 0; i < itemscount; i++) {View childView = adapter.getView(i, null, listview);childView.measure(View.MeasureSpec.makeMeasureSpec(listview.getWidth(), View.MeasureSpec.EXACTLY),View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));childView.layout(0, 0, childView.getMeasuredWidth(), childView.getMeasuredHeight());childView.setDrawingCacheEnabled(true);childView.buildDrawingCache();bmps.add(childView.getDrawingCache());allitemsheight += childView.getMeasuredHeight();//这里可以把listview中单独的item进行保存// viewSaveToImage(childView.getDrawingCache());}int w = listview.getMeasuredWidth();Bitmap bigbitmap = Bitmap.createBitmap(w, allitemsheight, Bitmap.Config.ARGB_8888);Canvas bigcanvas = new Canvas(bigbitmap);Paint paint = new Paint();int iHeight = 0;for (int i = 0; i < bmps.size(); i++) {Bitmap bmp = bmps.get(i);bigcanvas.drawBitmap(bmp, 0, iHeight, paint);iHeight += bmp.getHeight();bmp.recycle();bmp = null;}return bigbitmap;}

4. recycleview截图

recycleview和listView使用相同的方案

/*** recycleview截图* @param view* @return*/public static Bitmap shotRecyclerView(RecyclerView view) {RecyclerView.Adapter adapter = view.getAdapter();Bitmap bigBitmap = null;if (adapter != null) {int size = adapter.getItemCount();int height = 0;Paint paint = new Paint();int iHeight = 0;final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);// Use 1/8th of the available memory for this memory cache.final int cacheSize = maxMemory / 8;LruCache<String, Bitmap> bitmaCache = new LruCache<>(cacheSize);for (int i = 0; i < size; i++) {RecyclerView.ViewHolder holder = adapter.createViewHolder(view, adapter.getItemViewType(i));adapter.onBindViewHolder(holder, i);holder.itemView.measure(View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY),View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));holder.itemView.layout(0, 0, holder.itemView.getMeasuredWidth(),holder.itemView.getMeasuredHeight());holder.itemView.setDrawingCacheEnabled(true);holder.itemView.buildDrawingCache();Bitmap drawingCache = holder.itemView.getDrawingCache();if (drawingCache != null) {bitmaCache.put(String.valueOf(i), drawingCache);}height += holder.itemView.getMeasuredHeight();}bigBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), height, Bitmap.Config.ARGB_8888);Canvas bigCanvas = new Canvas(bigBitmap);Drawable lBackground = view.getBackground();if (lBackground instanceof ColorDrawable) {ColorDrawable lColorDrawable = (ColorDrawable) lBackground;int lColor = lColorDrawable.getColor();bigCanvas.drawColor(lColor);}for (int i = 0; i < size; i++) {Bitmap bitmap = bitmaCache.get(String.valueOf(i));bigCanvas.drawBitmap(bitmap, 0f, iHeight, paint);iHeight += bitmap.getHeight();bitmap.recycle();}}return bigBitmap;}

5. 任意View转bitmap

/*** view转bitmap*/public Bitmap viewConversionBitmap(View v) {int w = v.getWidth();int h = v.getHeight();Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);Canvas c = new Canvas(bmp);c.drawColor(Color.WHITE);/** 如果不设置canvas画布为白色,则生成透明 */v.layout(0, 0, w, h);v.draw(c);return bmp;}

注意:这里的view只能是已经显示在界面上的,那没显示在界面上的怎么处理?往下看

此方法也是后台生成view的方法:

/*** 计算view的大小*/public void measureSize(Activity activity, String url) {//将布局转化成view对象View viewBitmap = LayoutInflater.from(activity).inflate(R.layout.background_layout, null);WindowManager manager = activity.getWindowManager();DisplayMetrics outMetrics = new DisplayMetrics();manager.getDefaultDisplay().getMetrics(outMetrics);int width = outMetrics.widthPixels;int height = outMetrics.heightPixels;//然后View和其内部的子View都具有了实际大小,也就是完成了布局,相当与添加到了界面上。接着就可以创建位图并在上面绘制了:layoutView(viewBitmap, width, height, url, activity);}/*** 填充布局内容 */public void layoutView(final View viewBitmap, int width, int height, String url, Activity activity) {// 整个View的大小 参数是左上角 和右下角的坐标viewBitmap.layout(0, 0, width, height);int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.AT_MOST);viewBitmap.measure(measuredWidth, measuredHeight);viewBitmap.layout(0, 0, viewBitmap.getMeasuredWidth(), viewBitmap.getMeasuredHeight());TextView tv = viewBitmap.findViewById(R.id.tv_background);tv.setText("这是后台生成图片的标题");final ImageView imageView = viewBitmap.findViewById(R.id.iv_background);//注意加载网络图片时一定要用SimpleTarget回调Glide.with(activity).load(url).asBitmap().into(new SimpleTarget<Bitmap>() {@Overridepublic void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {imageView.setImageBitmap(resource);viewSaveToImage(viewBitmap);}});}/*** 把view转成图片* @param view*/private void viewSaveToImage(View view) {view.setDrawingCacheEnabled(true);view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);view.setDrawingCacheBackgroundColor(Color.WHITE);// 把一个View转换成图片Bitmap cachebmp = viewConversionBitmap(view);if (mBitmapDoneListener != null){mBitmapDoneListener.bitmapDone(cachebmp);}view.destroyDrawingCache();}

6. 圆角画中画

/*** view转bitmap*/public Bitmap viewConversionBitmap(View v) {int w = v.getWidth();int h = v.getHeight();Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);Canvas c = new Canvas(bmp);c.drawColor(Color.WHITE);/** 如果不设置canvas画布为白色,则生成透明 */v.layout(0, 0, w, h);v.draw(c);return bmp;}/*** 把上面获得的bitmap传进来就可以得到圆角的bitmap了*/public void bitmapInBitmap(Bitmap bitmap, ImageView imageView) {Bitmap tempBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);Canvas canvas = new Canvas(tempBitmap);//图像上画矩形Paint paint = new Paint();paint.setColor(Color.TRANSPARENT);paint.setStyle(Paint.Style.STROKE);//不填充paint.setStrokeWidth(10); //线的宽度canvas.drawRect(10, 20, 100, 100, paint);imageView.setImageBitmap(tempBitmap);//画中画Paint photoPaint = new Paint(); // 建立画笔photoPaint.setDither(true); // 获取跟清晰的图像采样photoPaint.setFilterBitmap(true);// 过滤一些Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());// 创建一个指定的新矩形的坐标Rect dst = new Rect(0, 0, 300, 350);// 创建一个指定的新矩形的坐标canvas.drawBitmap(tempBitmap, src, dst, photoPaint);// 将photo 缩放或则扩大到imageView.setImageBitmap(getRoundedCornerBitmap(tempBitmap));}/*** 生成圆角图片*/public Bitmap getRoundedCornerBitmap(Bitmap bitmap) {try {Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(output);final Paint paint = new Paint();final Rect rect = new Rect(0, 0, bitmap.getWidth(),bitmap.getHeight());final RectF rectF = new RectF(new Rect(0, 0, bitmap.getWidth(),bitmap.getHeight()));//设置圆角大小final float roundPx = 30;paint.setAntiAlias(true);canvas.drawARGB(0, 0, 0, 0);paint.setColor(Color.BLACK);canvas.drawRoundRect(rectF, roundPx, roundPx, paint);paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));final Rect src = new Rect(0, 0, bitmap.getWidth(),bitmap.getHeight());canvas.drawBitmap(bitmap, src, rect, paint);return output;} catch (Exception e) {return bitmap;}}

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

再次提醒一下:加载网络图片要使用simpleTarget回调,直接加载得到的是一片空白,切记!!!

目前博主只试过glide一种图片框架,其他框架请自行试验

原文链接:/p/3d03c66cf169

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。