Android Base64轉圖片

最近作一個項目裏面有關於圖片展現的需求,可是任性的後臺跟我說沒有圖片服務器,只能給我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版本):ide

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一次,改完以後還算滿意,基本上內存能夠保持穩定,好了,先到這了,有啥寫的很差的多多見諒,或者能夠共同探討。。函數

相關文章
相關標籤/搜索