关于View转化成bitmap保存成图片
产品今天说项目分享时要分享出一张 封面图片 + 几行文字 + 二维码图片 的图片。
思索了一下 封面图片和二维码图片让后台给接口得到地址, 主要还是找个方式得到一个包含这些内容的图片。于是就想能不能将View转化成bitmap对象
然后就走了一遍各个前辈的路 整理了下原理和思路。
根据产品的需求 我要实现的步骤 把所有需要的集合在一个View里 —— View转化成bitmap —— 分享出去(第三方分享bitmap对象)
接着搞个demo 实验一下
要转化的view 大致长这样
view_photo.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <ScrollView
- android:id="@+id/textView"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <!--封面图片 -->
- <ImageView
- android:layout_width="400dp"
- android:layout_height="400dp"
- android:background="@drawable/ic_launcher"
- android:layout_gravity="center_horizontal" />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="文字 文字"
- android:layout_gravity="center_horizontal" />
- <Button
- android:id="@+id/button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="假装是二维码图片"
- android:layout_gravity="center_horizontal" />
- </LinearLayout>
- </ScrollView>
- </LinearLayout>
最关键的View转bitmap
好像是有两种方法
- view.setDrawingCacheEnabled(true);
- view.buildDrawingCache(); //启用DrawingCache并创建位图
- Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache()); //创建一个DrawingCache的拷贝,因为DrawingCache得到的位图在禁用后会被回收
- view.setDrawingCacheEnabled(false); //禁用DrawingCahce否则会影响性能
- private Bitmap loadBitmapFromView(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;
- }
- DisplayMetrics metric = new DisplayMetrics();
- getWindowManager().getDefaultDisplay().getMetrics(metric);
- int width = metric.widthPixels; // 屏幕宽度(像素)
- int height = metric.heightPixels; // 屏幕高度(像素)
- View view = LayoutInflater.from(this).inflate(R.layout.view_photo, null, false);
- layoutView(view, width, height);//去到指定view大小的函数
- //然后View和其内部的子View都具有了实际大小,也就是完成了布局,相当与添加到了界面上。接着就可以创建位图并在上面绘制了:
- private void layoutView(View v, int width, int height) {
- // 指定整个View的大小 参数是左上角 和右下角的坐标
- v.layout(0, 0, width, height);
- int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
- int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.AT_MOST);
- /** 当然,measure完后,并不会实际改变View的尺寸,需要调用View.layout方法去进行布局。
- * 按示例调用layout函数后,View的大小将会变成你想要设置成的大小。
- */
- v.measure(measuredWidth, measuredHeight);
- v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
- }
在int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.AT_MOST);
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context="com.example.aa.MainActivity" >
- <Button
- android:id="@+id/button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text=" button" />
- <ImageView
- android:id="@+id/aaa"
- android:layout_below="@+id/button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- </RelativeLayout>
view_photo.xml 在上面
- public class MainActivity extends Activity {
- ImageView aaa ;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- DisplayMetrics metric = new DisplayMetrics();
- getWindowManager().getDefaultDisplay().getMetrics(metric);
- int width = metric.widthPixels; // 屏幕宽度(像素)
- int height = metric.heightPixels; // 屏幕高度(像素)
- View view = LayoutInflater.from(this).inflate(R.layout.view_photo, null, false);
- layoutView(view, width, height);
- final ScrollView tv = (ScrollView) view.findViewById(R.id.textView);
- aaa = (ImageView) findViewById(R.id.aaa);
- final Runnable runnable = new Runnable() {
- @Override
- public void run() {
- viewSaveToImage(tv);
- }
- };
- Button button = (Button) findViewById(R.id.button);
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- new Handler().post(runnable);
- }
- });
- }
- //然后View和其内部的子View都具有了实际大小,也就是完成了布局,相当与添加到了界面上。接着就可以创建位图并在上面绘制了:
- private void layoutView(View v, int width, int height) {
- // 整个View的大小 参数是左上角 和右下角的坐标
- v.layout(0, 0, width, height);
- int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
- int measuredHeight = View.MeasureSpec.makeMeasureSpec(10000, View.MeasureSpec.AT_MOST);
- /** 当然,measure完后,并不会实际改变View的尺寸,需要调用View.layout方法去进行布局。
- * 按示例调用layout函数后,View的大小将会变成你想要设置成的大小。
- */
- v.measure(measuredWidth, measuredHeight);
- v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
- }
- public void viewSaveToImage(View view) {
- Log.e("ssh","a");
- /**
- * View组件显示的内容可以通过cache机制保存为bitmap
- * 我们要获取它的cache先要通过setDrawingCacheEnable方法把cache开启,
- * 然后再调用getDrawingCache方法就可 以获得view的cache图片了
- * 。buildDrawingCache方法可以不用调用,因为调用getDrawingCache方法时,
- * 若果 cache没有建立,系统会自动调用buildDrawingCache方法生成cache。
- * 若果要更新cache, 必须要调用destoryDrawingCache方法把旧的cache销毁,才能建立新的。
- */
- // view.setDrawingCacheEnabled(true);
- // view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
- //设置绘制缓存背景颜色
- // view.setDrawingCacheBackgroundColor(Color.WHITE);
- // 把一个View转换成图片
- Bitmap cachebmp = loadBitmapFromView(view);
- aaa.setImageBitmap(cachebmp);//直接展示转化的bitmap
- //保存在本地 产品还没决定要不要保存在本地
- FileOutputStream fos;
- try {
- // 判断手机设备是否有SD卡
- boolean isHasSDCard = Environment.getExternalStorageState().equals(
- android.os.Environment.MEDIA_MOUNTED);
- if (isHasSDCard) {
- // SD卡根目录
- File sdRoot = Environment.getExternalStorageDirectory();
- Log.e("ssh",sdRoot.toString());
- File file = new File(sdRoot, "test.png");
- fos = new FileOutputStream(file);
- } else
- throw new Exception("创建文件失败!");
- //压缩图片 30 是压缩率,表示压缩70%; 如果不压缩是100,表示压缩率为0
- cachebmp.compress(Bitmap.CompressFormat.PNG, 90, fos);
- fos.flush();
- fos.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- view.destroyDrawingCache();
- }
- private Bitmap loadBitmapFromView(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;
- }
- }
demo转化成结果的bitmap和图片
关于View转化成bitmap保存成图片的更多相关文章
- BitmapUtil【缩放bitmap以及将bitmap保存成图片到SD卡中】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 用于缩放bitmap以及将bitmap保存成图片到SD卡中 效果图 代码分析 bitmapZoomByHeight(Bitmap s ...
- 如何把Excel中的单元格等对象保存成图片
对于Excel中的很多对象,比如单元格(Cell),图形(shape),图表(chart)等等,有时需要将它们保存成一张图片.就像截图一样. 最近做一个Excel相关的项目,项目中遇到一个很变态的需求 ...
- OpenGL中的深度、深度缓存、深度测试及保存成图片
1.深度 所谓深度,就是在openGL坐标系中,像素点Z坐标距离摄像机的距离.摄像机可能放在坐标系的任何位置,那么,就不能简单的说Z数值越大或越小,就是越靠近摄像机. 2.深度缓冲区 深度缓冲区原理就 ...
- javacpp-opencv图像处理之1:实时视频添加文字水印并截取视频图像保存成图片,实现文字水印的字体、位置、大小、粗度、翻转、平滑等操作
欢迎大家积极开心的加入讨论群 群号:371249677 (点击这里进群) javaCV图像处理系列: javaCV图像处理之1:实时视频添加文字水印并截取视频图像保存成图片,实现文字水印的字体.位置. ...
- 修改css的(屏蔽)overflow: hidden;实现浏览器能把网页全图保存成图片
摘要: 1.项目需要,需要对网页内容“下载”保存成全图片 2.QQ浏览器等主流浏览器都支持这种下载保存功能 3.项目需要场景:编写好的项目维护文档,放在服务器上.如果是txt不能带图片可视化,如果wo ...
- Java 将 PPT 形状(表格、文本框、心形、图表等)保存成图片
MS PowerPoint中的表格.文本框.心形.图表.图片等均可以称为形状,将这些形状保存成图片,便可分类储存,方便日后查找,再利用. 本文将介绍如何使用 Spire.Presentation fo ...
- 如何实现批量截取整个网页完整长截图,批量将网页保存成图片web2pic/webshot/screencapture/html2picture
如何实现批量截取整个网页完整长截图,批量将网页保存成图片web2pic/webshot/screencapture [困扰?疑问?]: 您是否正受到:如何将网页保存为图片的困扰?网页很高很长截图截不全 ...
- c# 将byte数组保存成图片
将byte数组保存成图片: 方式一:System.IO.File.WriteAllBytes(@"c:\test.jpg", bytes); 方式二:MemoryStream ms ...
- MVC下 把数据库中的byte[]值保存成图片,并显示在view页面
MVC下 把数据库中的byte[]值转成图片,并显示在view页面 controller中的action方法 //显示图片[AllowAnonymous]public ActionResult Sho ...
随机推荐
- 济南学习 Day 5 T1 am
炮(cannon)[题目描述]众所周知,双炮叠叠将是中国象棋中很厉害的一招必杀技.炮吃子时必须隔一个棋子跳吃,即俗称“炮打隔子”. 炮跟炮显然不能在一起打起来,于是rly一天借来了许多许多的炮在棋盘上 ...
- 【网摘】sql 语句修改字段名称以及字段类型
网上摘抄,备份使用: 修改字段名: 下例将表 customers 中的列 contact title 重命名为 title. EXEC sp_rename 'customers.[contact ti ...
- 转载自csdn http://blog.csdn.net/ithomer/article/details/6035627 Vim的分屏功能
Vim的分屏功能 目录(?)[+] 本篇文章主要教你如何使用 Vim 分屏功能 分屏启动Vim 使用小写的o参数来上下分屏(横向分屏). vim -on file1 file2 ... 使用大写的O参 ...
- bash变量类型详解
本地变量:作用于当前shell,对当前shell之外的其他shell进程和当前shell子进程均无效. 本地变量赋值为 name='value' value可以是字符串或者是变量,引用变量使用${na ...
- ubuntu下用webbench做网站压力测试
安装依赖 exuberant-ctags sudo apt-get install exuberant-ctags 下载源码并安装 wget http://blog.s135.com/soft/lin ...
- 迁移桌面程序到MS Store(8)——通过APPX下载Win32Component
在上一篇<迁移桌面程序到MS Store(7)——APPX + Service>中,我们提到将desktop application拆分成UI Client+Service两部分.其中UI ...
- Invocation of destroy method failed on bean with name ‘XXXX’
项目启动报错问题:Invocation of destroy method failed on bean with name 'scopedTarget.eurekaClient': org.spri ...
- underscore.js 页面数据渲染
1.underscore.js 源码 // Underscore.js 1.8.3 // http://underscorejs.org // (c) 2009-2015 Jeremy Ashken ...
- android的armeabi和armeabi-v7a
在ANE中如果SDK调用了so库,则需要把so库放到ANE下Android-ARM/lib/armeabi (调试模式)或者 armeabi-v7a(发行模式)下. 可以贴个ADT代码说明问题: // ...
- 自己定义html中a标签的title提示tooltip
自己定义html中a标签的title提示tooltip 简单介绍 用简单的jquery+CSS创建自己定义的a标签title提示,用来取代浏览器默认行为.如图: watermark/2/text/aH ...