最近做一个项目里面有关于图片展示的需求,但是任性的后台跟我说没有图片服务器,只能给我base64让我自己转成图片,好吧,我忍,转就转吧。。

首先第一步咱还是谦虚点上百度查查别人咋转的,结果似乎各位码友关于这方面的需求还是不多啊,查来查去普遍的是这样的:

/**
* bitmap转为base64
* @param bitmap
* @return
*/
public static String bitmapToBase64(Bitmap bitmap) { String result = null;
ByteArrayOutputStream baos = null;
try {
if (bitmap != null) {
baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); baos.flush();
baos.close(); byte[] bitmapBytes = baos.toByteArray();
result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (baos != null) {
baos.flush();
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
} /**
* base64转为bitmap
* @param base64Data
* @return
*/
public static Bitmap base64ToBitmap(String base64Data) {
byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}

楼主主要用到了base64转bitmap的方法,这个方法看上去没什么毛病,but。。。但是。。BitmapFactory.decodeByteArray这个方法是很邪恶的,BitmapFactory每次都会为新decode的bitmap分配内存,所以很容易造成oom,楼主为求真实性,手动刷新了几下我们的页面,然后就看着内存蹭蹭的往上涨,结果很快就oom了,所以这个所谓的往上代码并不可取,果断抛弃了,自己来改造一个,贴上自己的代码(Kotlin版本):

object ImageUtil {

    private var mMemoryCache: LruCache<String, Bitmap> ?= null
private var cacheSize:Int = 0 /**
* bitmap转为base64
* @param bitmap
* @return
*/
public fun bitmapToBase64(bitmap: Bitmap): String {
var result = ""
var baos: ByteArrayOutputStream? = null
try {
if (bitmap != null) {
baos = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos) baos!!.flush()
baos!!.close() val bitmapBytes = baos!!.toByteArray()
result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT)
}
} catch (e: IOException) {
e.printStackTrace()
} finally {
try {
if (baos != null) {
baos!!.flush()
baos!!.close()
}
} catch (e: IOException) {
e.printStackTrace()
} }
return result
} /**
* base64转为bitmap
* @param base64Data
* @return
*/
public fun base64ToBitmap(base64Data: String): Bitmap? {
if(cacheSize == 0){
// 获取到可用内存的最大值,使用内存超出这个值会引起OutOfMemory异常。
// LruCache通过构造函数传入缓存值,以KB为单位。
val maxMemory = Runtime.getRuntime().maxMemory() / 1024
// 使用最大可用内存值的1/8作为缓存的大小。
cacheSize = (maxMemory / 8).toInt()
} if(mMemoryCache == null){
mMemoryCache = object : LruCache<String, Bitmap>(cacheSize) {
override fun sizeOf(key: String?, bitmap: Bitmap?): Int {
// 重写此方法来衡量每张图片的大小,默认返回图片数量。
return bitmap!!.byteCount / 1024
}
}
} var bitmap: Bitmap? = null
var imgByte: ByteArray? = null
var inputStream:InputStream ?= null
try {
mMemoryCache?.get(base64Data)?.let {
bitmap = it
}
if(bitmap == null){
imgByte = Base64.decode(base64Data, Base64.DEFAULT)
val option = BitmapFactory.Options()
option.inSampleSize = 2
option.inTempStorage = ByteArray(5*1024*1024)
inputStream = ByteArrayInputStream(imgByte)
val softReference = SoftReference(BitmapFactory.decodeStream(inputStream, null, option))
bitmap = softReference.get()
softReference.clear()
mMemoryCache?.put(base64Data, bitmap)
} } catch (e: Exception) {
e.printStackTrace()
}finally {
imgByte = null
try {
inputStream?.close()
System.gc()
} catch (e: IOException) {
e.printStackTrace()
}
}
return bitmap
} }

通过内存缓存机制加上软应用,保证同一张图片只decode一次,改完之后还算满意,基本上内存可以保持稳定,好了,先到这了,有啥写的不好的多多见谅,或者可以共同探讨。。

Android Base64转图片的更多相关文章

  1. Android Base64图片无法长按保存 问题解决

    踩了一个巨坑. 目前微信ios/android 均能长按保存src=base64的图片  (微信android x5 专门解决了这个问题); 但是android其他App没有针对解决这个系统问题(姑且 ...

  2. Android - Base64

    Android 将图片转换为Base64 public void convertToBase64(View view) throws IOException { //获取ImageView的图片 Bi ...

  3. laravel 存储base64格式图片

    laravel 存储base64格式图片 一.总结 一句话总结: 用正则替换base64图片编码的编码头即可 存储图片的话,用laravel可以用Storage的put方法,原生php可以用file_ ...

  4. android获得ImageView图片的等级

    android获得ImageView图片的等级问题 要实现的功能如下图,点击分享能显示选中与不选中状态,然后发送是根据状态来实现具体分享功能. 在gridview中有5个子项,每个子元素都有两张图片A ...

  5. 页面以base64输出图片

    <% //读取文件路径,输出base64 编码 System.IO.FileStream stream = System.IO.File.OpenRead(ViewBag.FilePath); ...

  6. base64和图片的转换

    /// <summary> /// base64转图片 /// </summary> /// <param name="strBase64">& ...

  7. 解决android:background背景图片被拉伸问题

    ImageView中XML属性src和background的区别: background会根据ImageView组件给定的长宽进行拉伸,而src就存放的是原图的大小,不会进行拉伸.src是图片内容(前 ...

  8. Android  PNG透明图片转JPG格式背景变黑

    Android  PNG透明图片转JPG格式背景变黑 在上传图片是,需要把PNG格式转换成JPG格式的,但是在遇上透明背景时,转过来就变成黑色底图了! 原因是PNG支持透明图而 JPG格式不支持透明底 ...

  9. 通过data:image/png;base64把图片直接写在src里

    从网上下了个源文件查看时候发现了引用图片的地址不是在本地上的,而是后面跟了一大串字符data:image/png;base64...查了一下资料分析如下: 关于用base64存储图片 网页上有些图片的 ...

随机推荐

  1. jenkins 之 Android 打包及上传至蒲公英

    准备条件 iMAC,非必须(如果是 安卓 和 苹果 可以在同一台电脑上打包则要 Mac OS 系统的电脑,如果是只是给安卓打包 windows 电脑也是可以的, window 下 需要把 ls 换成 ...

  2. 令人惊叹的Visual Studio Code插件

    vscode是一款开源且优秀的编辑器,接下来让我吐血推荐一下我工作使用过的令人惊叹的Visual Studio Code插件. 代码编辑插件 vscode-color-highlight ------ ...

  3. Selenium WebDriver-操作页面下拉列表

    #encoding=utf-8 import unittest import time import chardet from selenium import webdriver class Visi ...

  4. $.each 用break 好像不太灵啊

    for(var i=0;i<obj.length;i++) {                                       if (i < 5) {             ...

  5. 博客笔记(blog notebook)

    1. 机器学习 2. NLP 3. code 实际好人 实际坏人 预测百分比 预测好人 \(p_GF^c(s_c\|G)\) \(p_BF^c(s_c\|B)\) \(F^c(s_c)\) 预测坏人 ...

  6. [uiautomator篇][exist 存在,但click错误]

    uiautomator定位页面元素是,定位存在的;但是click的时候,发现点的位置不对,(不知道是android系统的问题还是uiautomator的问题,初步怀疑是系统的问题)

  7. 连通图 poj2186 最受欢迎的牛(求最受欢迎的牛的数量)

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27531   Accepted: 11077 De ...

  8. LibreOJ2043 - 「CQOI2016」K 远点对

    Portal Description 给出平面上的\(n(n\leq10^5)\)个整点,求在欧几里得距离下第\(k\)远的点对之间的距离. Solution k-d树+堆. 用小根堆维护当前找到的第 ...

  9. vue-resource发送multipart/form-data数据

    //add headers this.$http.post('/api', data, { headers: { 'Content-Type': 'multipart/form-data' } }) ...

  10. 学习的一些mybatis

    MyBatis入门基础(一) 阅读目录 一:对原生态JDBC问题的总结 二:MyBatis框架 三:mybatis入门程序 四:mybatis和Hibernate的本质区别与应用场景 五:小结 回到顶 ...