当前位置:   article > 正文

Android View转为图片保存为本地文件,异步监听回调操作结果;_android 保存图片是耗时操作吗

android 保存图片是耗时操作吗

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

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

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

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

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

6.0动态权限:

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

如何使用:

  1. ViewSaveImageUtils.savePhotoToSDCard(scrollView, new ViewSaveImageUtils.OnSaveListEner() {
  2. @Override
  3. public void onStart() {
  4. runOnUiThread(() -> showProgressDialog("生成图片...")); //显示dialog
  5. L.cc("开始");
  6. }
  7. @Override
  8. public void onSucceed(String filePath) {
  9. L.cc("成功:"+filePath);
  10. }
  11. @Override
  12. public void onFailure(String error) {
  13. L.cc("失败"+error);
  14. }
  15. @Override
  16. public void onFinish() {
  17. L.cc("结束");
  18. runOnUiThread(() -> dismissProgressDialog()); //隐藏dialog
  19. }
  20. });

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

  1. import android.graphics.Bitmap;
  2. import android.graphics.Canvas;
  3. import android.graphics.Color;
  4. import android.os.Environment;
  5. import android.view.View;
  6. import android.widget.ScrollView;
  7. import java.io.File;
  8. import java.io.FileNotFoundException;
  9. import java.io.FileOutputStream;
  10. import java.io.IOException;
  11. /**
  12. * ChenboCui View转Bitmap 把图片保存到本地的工具类
  13. */
  14. public class ViewSaveImageUtils {
  15. /**
  16. * 把一个View转为图片保存到本地
  17. * @param view
  18. * @param ener
  19. */
  20. public static void viewSaveToImage(View view, OnSaveListEner ener) {
  21. if (ener != null) ener.onStart();
  22. // 把一个View转换成图片
  23. Bitmap cachebmp = loadBitmapFromView(view);
  24. FileOutputStream fos;
  25. if (checkSDCardAvailable()) {
  26. try {
  27. // SD卡根目录
  28. File sdRoot = AndroidUtils.getDownloadDir();
  29. File file = new File(sdRoot, System.currentTimeMillis() + ".png");
  30. fos = new FileOutputStream(file);
  31. cachebmp.compress(Bitmap.CompressFormat.PNG, 90, fos);
  32. fos.flush();
  33. fos.close();
  34. if (ener != null) ener.onSucceed(file.getAbsolutePath());
  35. } catch (Exception e) {
  36. if (ener != null) ener.onFailure(e.getMessage());
  37. e.printStackTrace();
  38. }
  39. } else {
  40. if (ener != null) ener.onFailure("创建文件失败!");
  41. }
  42. view.destroyDrawingCache();
  43. if (ener != null) ener.onFinish();
  44. }
  45. /**
  46. * 把一个View转为图片保存到本地
  47. * @param view
  48. * @return
  49. */
  50. public static String viewSaveToImage(View view) {
  51. // 把一个View转换成图片
  52. Bitmap cachebmp = loadBitmapFromView(view);
  53. FileOutputStream fos;
  54. String imagePath = "";
  55. try {
  56. if (checkSDCardAvailable()) {
  57. // SD卡根目录
  58. File sdRoot = AndroidUtils.getDownloadDir();
  59. File file = new File(sdRoot, System.currentTimeMillis() + ".png");
  60. fos = new FileOutputStream(file);
  61. imagePath = file.getAbsolutePath();
  62. } else {
  63. throw new Exception("创建文件失败!");
  64. }
  65. cachebmp.compress(Bitmap.CompressFormat.PNG, 90, fos);
  66. fos.flush();
  67. fos.close();
  68. } catch (Exception e) {
  69. e.printStackTrace();
  70. }
  71. L.cc("imagePath=" + imagePath);
  72. view.destroyDrawingCache();
  73. return imagePath;
  74. }
  75. /**
  76. * 把一个View转为Bitmap
  77. *
  78. * @param v
  79. * @return
  80. */
  81. public static Bitmap loadBitmapFromView(View v) {
  82. v.setDrawingCacheEnabled(true);
  83. v.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
  84. v.setDrawingCacheBackgroundColor(Color.WHITE);
  85. int w = v.getWidth();
  86. int h = v.getHeight();
  87. Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
  88. Canvas c = new Canvas(bmp);
  89. c.drawColor(Color.WHITE);
  90. /** 如果不设置canvas画布为白色,则生成透明 */
  91. v.layout(0, 0, w, h);
  92. v.draw(c);
  93. return bmp;
  94. }
  95. /**
  96. * Bitmap保存为图片
  97. *
  98. * @param photoBitmap
  99. * @param path
  100. * @param photoName
  101. */
  102. public static void savePhotoToSDCard(Bitmap photoBitmap, String path, String photoName) {
  103. if (checkSDCardAvailable()) {
  104. File dir = new File(path);
  105. if (!dir.exists()) {
  106. dir.mkdirs();
  107. }
  108. File photoFile = new File(path, photoName + ".png");
  109. FileOutputStream fileOutputStream = null;
  110. try {
  111. fileOutputStream = new FileOutputStream(photoFile);
  112. if (photoBitmap != null) {
  113. if (photoBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)) {
  114. fileOutputStream.flush();
  115. }
  116. } else {
  117. }
  118. } catch (FileNotFoundException e) {
  119. photoFile.delete();
  120. e.printStackTrace();
  121. } catch (IOException e) {
  122. photoFile.delete();
  123. e.printStackTrace();
  124. } finally {
  125. try {
  126. fileOutputStream.close();
  127. } catch (IOException e) {
  128. e.printStackTrace();
  129. }
  130. }
  131. }
  132. }
  133. /**
  134. * ScrollView保存为图片
  135. *
  136. * @param scrollView
  137. * @param path
  138. * @param photoName
  139. */
  140. public static void savePhotoToSDCard(ScrollView scrollView, String path, String photoName, OnSaveListEner ener) {
  141. //耗时操作,放线程处理
  142. new Thread(new Runnable() {
  143. @Override
  144. public void run() {
  145. if (ener != null) ener.onStart();
  146. if (checkSDCardAvailable()) {
  147. File dir = new File(path);
  148. if (!dir.exists()) {
  149. dir.mkdirs();
  150. }
  151. File photoFile = new File(path, photoName + ".png");
  152. FileOutputStream fileOutputStream = null;
  153. try {
  154. Bitmap photoBitmap = getBitmapByView(scrollView);
  155. fileOutputStream = new FileOutputStream(photoFile);
  156. if (photoBitmap != null) {
  157. if (photoBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)) {
  158. fileOutputStream.flush();
  159. }
  160. if (ener != null) ener.onSucceed(photoFile.getAbsolutePath());
  161. } else {
  162. if (ener != null) ener.onFailure("Bitmap = NULL");
  163. }
  164. } catch (FileNotFoundException e) {
  165. if (ener != null) ener.onFailure("FileNotFoundException");
  166. photoFile.delete();
  167. e.printStackTrace();
  168. } catch (IOException e) {
  169. if (ener != null) ener.onFailure("IOException");
  170. photoFile.delete();
  171. e.printStackTrace();
  172. } finally {
  173. try {
  174. fileOutputStream.close();
  175. } catch (IOException e) {
  176. e.printStackTrace();
  177. }
  178. }
  179. } else {
  180. if (ener != null) ener.onFailure("文件储存异常");
  181. }
  182. if (ener != null) ener.onFinish();
  183. }
  184. }).start();
  185. }
  186. public static void savePhotoToSDCard(ScrollView scrollView, OnSaveListEner ener) {
  187. String path = AndroidUtils.getDownloadDir().getAbsolutePath();
  188. String photoname = "maxus" + System.currentTimeMillis();
  189. savePhotoToSDCard(scrollView, path, photoname, ener);
  190. }
  191. /**
  192. * 把一个View转为Bitmap
  193. *
  194. * @param scrollView
  195. * @return
  196. */
  197. public static Bitmap getBitmapByView(ScrollView scrollView) {
  198. int h = 0;
  199. Bitmap bitmap = null;
  200. for (int i = 0; i < scrollView.getChildCount(); i++) {
  201. h += scrollView.getChildAt(i).getHeight();
  202. }
  203. bitmap = Bitmap.createBitmap(scrollView.getWidth(), h,
  204. Bitmap.Config.RGB_565);
  205. final Canvas canvas = new Canvas(bitmap);
  206. canvas.drawColor(Color.WHITE); //白色背景
  207. scrollView.draw(canvas);
  208. return bitmap;
  209. }
  210. public static boolean checkSDCardAvailable() {
  211. return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
  212. }
  213. public interface OnSaveListEner {
  214. void onStart();
  215. void onSucceed(String filePath);
  216. void onFailure(String error);
  217. void onFinish();
  218. }
  219. }

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

  1. public static File getDownloadDir() {
  2. File downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
  3. if (!downloadDir.exists()) {
  4. downloadDir.mkdir();
  5. }
  6. return downloadDir;
  7. }

好了,大功告成!!!

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

闽ICP备14008679号