把手机上的一个View或ViewGroup转为Bitmap,再把Bitmap保存为.png格式的图片;

由于View转Bitmap、和Bitmap转图片都是耗时操作,(生成一个1M的图片大约500ms,如果图片过大,用户会觉得APP卡顿,甚至ANR)我在子线程进行处理,然后把保存的结果回调出来;

监听回调分别是: 开始、成功、失败、完成; 可以在各个回调中做处理;

由于用到了读写本地文件的权限,记得给该APP分配权限;

   <!-- SDCard创建删除文件 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- SDCard读写 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

6.0动态权限:

    private boolean storagePermission(){
//动态获取内存存储权限
int permission = ActivityCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
1);
return false;
}else{
return true;
}
}

如何使用:

 ViewSaveImageUtils.savePhotoToSDCard(scrollView, new ViewSaveImageUtils.OnSaveListEner() {

            @Override
public void onStart() {
runOnUiThread(() -> showProgressDialog("生成图片...")); //显示dialog
L.cc("开始");
} @Override
public void onSucceed(String filePath) {
L.cc("成功:"+filePath);
} @Override
public void onFailure(String error) {
L.cc("失败"+error);
} @Override
public void onFinish() {
L.cc("结束");
runOnUiThread(() -> dismissProgressDialog()); //隐藏dialog
}
});

View转为图片文件的工具类,注释很详细,不多解释了;



import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Environment;
import android.view.View;
import android.widget.ScrollView;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException; /**
* ChenboCui View转Bitmap 把图片保存到本地的工具类
*/
public class ViewSaveImageUtils { /**
* 把一个View转为图片保存到本地
* @param view
* @param ener
*/
public static void viewSaveToImage(View view, OnSaveListEner ener) {
if (ener != null) ener.onStart();
// 把一个View转换成图片
Bitmap cachebmp = loadBitmapFromView(view);
FileOutputStream fos;
if (checkSDCardAvailable()) {
try {
// SD卡根目录
File sdRoot = AndroidUtils.getDownloadDir();
File file = new File(sdRoot, System.currentTimeMillis() + ".png");
fos = new FileOutputStream(file);
cachebmp.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.flush();
fos.close();
if (ener != null) ener.onSucceed(file.getAbsolutePath());
} catch (Exception e) {
if (ener != null) ener.onFailure(e.getMessage());
e.printStackTrace();
}
} else {
if (ener != null) ener.onFailure("创建文件失败!");
}
view.destroyDrawingCache();
if (ener != null) ener.onFinish();
} /**
* 把一个View转为图片保存到本地
* @param view
* @return
*/
public static String viewSaveToImage(View view) {
// 把一个View转换成图片
Bitmap cachebmp = loadBitmapFromView(view); FileOutputStream fos;
String imagePath = "";
try {
if (checkSDCardAvailable()) {
// SD卡根目录
File sdRoot = AndroidUtils.getDownloadDir();
File file = new File(sdRoot, System.currentTimeMillis() + ".png");
fos = new FileOutputStream(file);
imagePath = file.getAbsolutePath();
} else {
throw new Exception("创建文件失败!");
}
cachebmp.compress(Bitmap.CompressFormat.PNG, 90, fos); fos.flush();
fos.close(); } catch (Exception e) {
e.printStackTrace();
}
L.cc("imagePath=" + imagePath); view.destroyDrawingCache();
return imagePath;
} /**
* 把一个View转为Bitmap
*
* @param v
* @return
*/
public static Bitmap loadBitmapFromView(View v) {
v.setDrawingCacheEnabled(true);
v.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
v.setDrawingCacheBackgroundColor(Color.WHITE); 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保存为图片
*
* @param photoBitmap
* @param path
* @param photoName
*/
public static void savePhotoToSDCard(Bitmap photoBitmap, String path, String photoName) {
if (checkSDCardAvailable()) {
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
} File photoFile = new File(path, photoName + ".png");
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(photoFile);
if (photoBitmap != null) {
if (photoBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)) {
fileOutputStream.flush();
}
} else { }
} catch (FileNotFoundException e) {
photoFile.delete();
e.printStackTrace();
} catch (IOException e) {
photoFile.delete();
e.printStackTrace();
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} /**
* ScrollView保存为图片
*
* @param scrollView
* @param path
* @param photoName
*/
public static void savePhotoToSDCard(ScrollView scrollView, String path, String photoName, OnSaveListEner ener) {
//耗时操作,放线程处理
new Thread(new Runnable() {
@Override
public void run() {
if (ener != null) ener.onStart();
if (checkSDCardAvailable()) {
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
} File photoFile = new File(path, photoName + ".png");
FileOutputStream fileOutputStream = null;
try {
Bitmap photoBitmap = getBitmapByView(scrollView);
fileOutputStream = new FileOutputStream(photoFile);
if (photoBitmap != null) {
if (photoBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)) {
fileOutputStream.flush();
}
if (ener != null) ener.onSucceed(photoFile.getAbsolutePath());
} else {
if (ener != null) ener.onFailure("Bitmap = NULL");
}
} catch (FileNotFoundException e) {
if (ener != null) ener.onFailure("FileNotFoundException");
photoFile.delete();
e.printStackTrace();
} catch (IOException e) {
if (ener != null) ener.onFailure("IOException");
photoFile.delete();
e.printStackTrace();
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
if (ener != null) ener.onFailure("文件储存异常");
}
if (ener != null) ener.onFinish();
}
}).start();
} public static void savePhotoToSDCard(ScrollView scrollView, OnSaveListEner ener) {
String path = AndroidUtils.getDownloadDir().getAbsolutePath();
String photoname = "maxus" + System.currentTimeMillis();
savePhotoToSDCard(scrollView, path, photoname, ener);
} /**
* 把一个View转为Bitmap
*
* @param scrollView
* @return
*/
public static Bitmap getBitmapByView(ScrollView scrollView) {
int h = 0;
Bitmap bitmap = null;
for (int i = 0; i < scrollView.getChildCount(); i++) {
h += scrollView.getChildAt(i).getHeight();
}
bitmap = Bitmap.createBitmap(scrollView.getWidth(), h,
Bitmap.Config.RGB_565);
final Canvas canvas = new Canvas(bitmap);
canvas.drawColor(Color.WHITE); //白色背景
scrollView.draw(canvas);
return bitmap;
} public static boolean checkSDCardAvailable() {
return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
} public interface OnSaveListEner {
void onStart(); void onSucceed(String filePath); void onFailure(String error); void onFinish();
} }

AndroidUtils.getDownloadDir(); 也是我的一个工具类,我把这个方法贴下来:

   public static File getDownloadDir() {
File downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
if (!downloadDir.exists()) {
downloadDir.mkdir();
}
return downloadDir;
}

好了,大功告成!!!

Android View转为图片保存为本地文件,异步监听回调操作结果;的更多相关文章

  1. React Native之图片保存到本地相册(ios android)

    React Native之图片保存到本地相册(ios android) 一,需求分析 1,react native保存网络图片到相册,iOS端可以用RN自带的CameraRoll完美解决,但是andr ...

  2. 2018-5-22-SublimeText-粘贴图片保存到本地

    title author date CreateTime categories SublimeText 粘贴图片保存到本地 lindexi 2018-05-22 15:15:26 +0800 2018 ...

  3. php 获取远程图片保存到本地

    php 获取远程图片保存到本地 使用两个函数 1.获取远程文件 2.把图片保存到本地 /** * 获取远程图片并把它保存到本地 * $url 是远程图片的完整URL地址,不能为空. */ functi ...

  4. 使用JavaScript将图片保存至本地

    在最近的开发当中,我们需要为img标签以及canvas动态绘制的图像提供下载功能,下面是经过探索后我们得出的结果. 一.Canvas 版本 // 下载Canvas元素的图片 function down ...

  5. 【Jmeter】jmeter提取response中的返回值,并保存到本地文件--BeanShell后置处理器

    有个需求,需要在压测环境中,创建几十万的账号数据,然后再根据创建结果,查询到某些账号信息. 按照之前我的做法,直接Python调用API,然后再数据库查询: 但是近期所有开发人员的数据库访问权限被限制 ...

  6. 微信小程序图片保存到本地

    微信小程序图片保存到本地是一个常用功能: 这里讲解下完整实现思路: 因为微信官方的授权只弹一次,用户拒绝后再次调用,就需要结合button组件的微信开放能力来调起,以下方案在微信各种授权中可参考. w ...

  7. JAVA 通过url下载图片保存到本地

    //java 通过url下载图片保存到本地 public static void download(String urlString, int i) throws Exception { // 构造U ...

  8. iOS 将图片保存到本地

    //将图片保存到本地 + (void)SaveImageToLocal:(UIImage*)image Keys:(NSString*)key {     NSUserDefaults* prefer ...

  9. iOS-iOS调用相机调用相册【将图片保存到本地相册】

    设置头部代理 <UINavigationControllerDelegate, UIImagePickerControllerDelegate> 1.调用相机 检测前置摄像头是否可用 - ...

随机推荐

  1. UVa——1600(巡逻机器人)

    迷宫求最短路的话一般用bfs都可以解决,但是这个加了个状态,那么就增加一个维度,用来判断k的值.比较简单的三维bfs.写搜索题的话一定要注意细节.这个题花了好长的时间.因为k的原因,一开始用了k的原因 ...

  2. vue 监听手机键盘是否弹出及input是否聚焦成功

    //定义移动端类型 function pageStats() { let u = navigator.userAgent, app = navigator.appVersion; let obj = ...

  3. 统计数字(关联容器map)

    题目描述 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*109).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统 ...

  4. 用雷达统计成绩单、numpy、matplotlib的使用

    #e19.1DrawRadar import numpy as np import matplotlib.pyplot as plt import matplotlib matplotlib.rcPa ...

  5. Ex0203

    游戏 –     这些软件的开发者是怎么说服你(陌生人)成为他们的用户的?他们的目标都是盈利么?他们的目标都是赚取用户的现金么?还是别的? 朋友们都在玩,我在试玩的时候也觉得很不错:游戏基本上的目标都 ...

  6. SSM学习笔记

    Spring MVC[入门]就这一篇! https://www.jianshu.com/p/91a2d0a1e45a SpringMVC非注解方式和注解方式不能同时使用.注解方式只需要配一句话就行了d ...

  7. 给jumpserver双机配置glusterfs共享复制卷

    为什么要使用glusterfs呢. 本身Haproxy+Keepalived对jumpserver进行了负载均衡和反向代理.但是真实的视频只会存储在一个节点上 否则播放视频的时候会出现找不到的情况 为 ...

  8. 密码疑云 (2)——RSA加密机制需要的数学知识

    在公钥密码体制提出不久,人们就找到其中的三种,其中最著名的当属RSA体制.RSA是一种非对称加密体制,在公开密钥加密和电子商业中被广泛使用.RSA是1977年由罗纳德·李维斯特(Ron Rivest) ...

  9. Asp.Net : Page.RegisterStartupScript及 不执行的原因

    RegisterStartupScript 把script放置在ASP.NET page的底部,而RegisterClientScriptBlock把script放置在ASP.NET page的顶部 ...

  10. 【转】计算机信息系统安全保护等级划分准则(GB 17859-1999)

    计算机信息系统安全保护等级划分准则(GB 17859-1999) 概述 计算机信息系统安全保护等级划分准则(GB 17859-1999) 1 范围 本标准规定了计算机系统安全保护能力的五个等级,即: ...