Android中图片优化之webp使用
博客出自:http://blog.csdn.net/liuxian13183,轉(zhuǎn)載注明出處! All Rights Reserved !
有關(guān)圖片的優(yōu)化,通常我們會(huì)用到LruCache(使用強(qiáng)引用、強(qiáng)制回收的辦法),會(huì)用到SoftReference(使用url做key,bitmap做value的方法),會(huì)用到根據(jù)手機(jī)屏幕來(lái)縮放圖片,會(huì)及時(shí)回收?qǐng)D片所占用的內(nèi)存等方法,但說(shuō)實(shí)在的,這些方法治標(biāo)不治本,圖片該多大還多大,從軟件上我們基本上能做到處理圖片的極限,那么只剩下考慮從硬件來(lái)上優(yōu)化圖片,這就講到了今天所要說(shuō)的webp。
其中webp不僅僅能應(yīng)用在Android上,同樣IOS和web端也同樣可以使用。
有關(guān)webp的簡(jiǎn)介,騰訊同學(xué)有詳細(xì)介紹,濃縮的精華!從零開(kāi)始帶你認(rèn)識(shí)最新的圖片格式WEBP,我不再多說(shuō)。
常用的webp轉(zhuǎn)換工具有:XnConvet,智圖,ISparta
一張279k的png圖片可以轉(zhuǎn)換成67.5k的webp圖片,而且不失真
第一步添加webp支持,添加so包和lib包
第二步,添加WebpUtils文件,里面有通過(guò)so包來(lái)處理webp文件成為byte數(shù)組的方法
第三步,應(yīng)用
效果圖:
你最想要的源碼!Android Service和webp講解源碼
附安卓SDK文檔給出的官方壓縮圖片算法:
public static Bitmap getBitmapBySize(String path, int width, int height) {BitmapFactory.Options option = new BitmapFactory.Options();option.inJustDecodeBounds = true;BitmapFactory.decodeFile(path, option);option.inSampleSize = computeSampleSize(option, -1, width * height);option.inJustDecodeBounds = false;Bitmap bitmap = null;try {bitmap = BitmapFactory.decodeFile(path, option);} catch (Exception e) {e.printStackTrace();}return bitmap;}public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);int roundedSize;if (initialSize <= 8) {roundedSize = 1;while (roundedSize < initialSize) {roundedSize <<= 1;}} else {roundedSize = (initialSize + 7) / 8 * 8;}return roundedSize;}private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {double w = options.outWidth;double h = options.outHeight;int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));if (upperBound < lowerBound) {// return the larger one when there is no overlapping zone.return lowerBound;}if ((maxNumOfPixels == -1) && (minSideLength == -1)) {return 1;} else if (minSideLength == -1) {return lowerBound;} else {return upperBound;}}
算法的意思是:將原圖壓縮為大概width*height個(gè)像素,原圖像素?cái)?shù)/(width*height)=壓縮比率^2,得到這個(gè)比率后,對(duì)原圖進(jìn)行等比例壓縮;避免的誤區(qū)是,以為放入的width*height就是要壓縮到的大小
壓縮像素為1280*720,保證清晰度同比壓縮到,如果超過(guò)則取更小值,因此文件大小不能確定,測(cè)試兩組數(shù)據(jù)如下:
原圖長(zhǎng)寬 ? ? 大小 ? 壓縮后長(zhǎng)寬 ? ? ?壓縮后大小 ? ? ? 長(zhǎng)寬比 ? 大小比 ? ? ?inSampleSize
3120*4160 3.41m 612*816 465kb(理論140)? 25.99? ? ? ? ? 7.5 ? ? ? ?5
2448*3264 1.43m 780*1040 265kb(理論160)? 9.85 ? ? ? ? ? ?5.53 ? ? ?3
2448*3264 1.8m 612*816 294kb(理論115) 16 ? ?6.27 ? ? ?4
圖片大小理論值都比實(shí)際值要小,可見(jiàn)圖片長(zhǎng)寬與大小不成正比;第三組數(shù)據(jù)和第一組數(shù)據(jù)共用一臺(tái)手機(jī),可見(jiàn)同一手機(jī)壓縮后的長(zhǎng)寬比是一致的。圖片大小壓縮大小最小為5倍;而一般情況下圖片解析得到的Bitmap大小會(huì)比文件大5倍左右。
另外頁(yè)面中重新定義的ImageView,如果使用當(dāng)前頁(yè)面的context作為引入,則當(dāng)頁(yè)面關(guān)閉后可能會(huì)引起內(nèi)存泄露,同時(shí)會(huì)引起OOM,引用鏈過(guò)長(zhǎng)同時(shí)未被釋放;方法是將Application作為context加入ImageView,在頁(yè)面destroy時(shí),清除context,以及View
public static void unbindDrawables(View view) {if (view.getBackground() != null) {view.getBackground().setCallback(null);}if (view instanceof ViewGroup) {for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {unbindDrawables(((ViewGroup) view).getChildAt(i));}((ViewGroup) view).removeAllViews();}}
借這個(gè)機(jī)會(huì)講講避免內(nèi)存泄露的方法:
Cursor用后及時(shí)關(guān)閉,Bitmap及對(duì)象及時(shí)回收,避免在循環(huán)體中new對(duì)象,注冊(cè)的廣播等監(jiān)聽(tīng)及時(shí)取消,盡量使用Application而非context。
其他內(nèi)存優(yōu)化的方法:http://www.diycode.cc/projects/cundong/MemoryMonitor
總結(jié)
以上是生活随笔為你收集整理的Android中图片优化之webp使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 《图书管理系统——java》
- 下一篇: AndroidWidget实践 ---