关于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 ...
随机推荐
- Redis命令行之String
一.Redis之String简介 1. String是redis最基本的数据类型,一个key对应一个value. 2. String是二进制安全的,可以包含任何数据,例如图片或序列化的对象. 3. S ...
- BZOJ 1090 字符串折叠(Hash + DP)
题目链接 字符串折叠 区间DP.$f[l][r]$为字符串在区间l到r的最小值 正常情况下 $f[l][r] = min(f[l][r], f[l][l+k-1]+f[l+k][r]);$ 当$l$到 ...
- Spring Boot 2 快速教程:WebFlux 集成 Mongodb(四)
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第104篇原创 文章工程:* JDK 1.8* M ...
- noip 2013 luogu P1969 积木大赛
题目描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi. 在搭建开始之前,没有任何积木(可以看成 ...
- uml精粹——10.状态机图
10.状态机图state machine diagram 状态机图是常见的描写叙述一个系统行为的技术. 在面向对象的方法中,为单个类绘制一个状态机图来展示单个对象的生命周期行为. 见图10.1 图 ...
- (转) SYSTEM_HANDLE_INFORMATION中ObjectTypeIndex的定义
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO{ USHORT UniqueProcessId; USHORT CreatorBackTraceIndex ...
- electron 开发拆坑总结
electron 总结 前言 有一个web项目需要用客户端来包装一下 项目的主要业务都在服务器上 所以项目的大多数功能都用url 地址来访问: 客户端登陆界面在本地 打包客户端的本地登陆界面 做为登陆 ...
- Java类载入器(二)——自己定义类载入器
用户定制自己的ClassLoader能够实现以下的一些应用: 自己定义路径下查找自己定义的class类文件,或许我们须要的class文件并不总是在已经设置好的Classpath以下,那么我们必须想 ...
- JDBC MYSQL 学习笔记(一) JDBC 基本使用
1.JDBC简单介绍 SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范.称之为JDBC. JDBC全称为:Java Data Base Connectivity(java数据 ...
- react 创建组件 (三)PureComponet
我们知道,当组件的props或者state发生变化的时候:React会对组件当前的Props和State分别与nextProps和nextState进行比较,当发现变化时,就会对当前组件以及子组件进行 ...