最近做一个项目里面有关于图片展示的需求,但是任性的后台跟我说没有图片服务器,只能给我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一次,改完之后还算满意,基本上内存可以保持稳定,好了,先到这了,有啥写的不好的多多见谅,或者可以共同探讨。。

最新文章

  1. yaf的简单入门
  2. 插件dTree的使用
  3. All About Python
  4. poj 1286&amp;&amp;poj2409 Polya计数 颜色匹配
  5. [译]git clone
  6. python多线程生成缩略图
  7. Java 如何有效地避免OOM:善于利用软引用和弱引用
  8. windows ssh RPi 2B
  9. C语言中的字节对齐以及其相关处理
  10. URL传参中文乱码encodeURI、UrlDecode
  11. 基于visual Studio2013解决面试题之0503取最大数字字符串
  12. python cookbook学习1
  13. C#多线程处理
  14. django学习系列——python和php对比
  15. 搭建Fabric网络(二)下载bin和images
  16. Use Reentrant Functions for Safer Signal Handling(译:使用可重入函数进行更安全的信号处理)
  17. js中文乱码
  18. cocos2d-x与ISO内存管理(转)
  19. Unity游戏接入Steam成就
  20. PHP删除临时文件

热门文章

  1. #1 add life to static pages &amp;&amp; connect to MySQL
  2. 线程中更新ui方法汇总
  3. spark作业
  4. 让 PHP COOKIE 立即生效(不用刷新就可以使用)
  5. 九度oj 题目1457:非常可乐
  6. 修改mysql数据的字符集校验规则使其区分大小写
  7. activemq的安装启动
  8. 设计模式(五)原型模式 Prototype
  9. ubuntu14.04修改mysql默认编码
  10. 【Luogu】P2447外星千足虫(高斯消元)