Android中圖片優化之webp使用



博客出自:http://blog.csdn.net/liuxian13183,轉載注明出處! All Rights Reserved !


有關圖片的優化,通常我們會用到LruCache(使用強引用、強制回收的辦法),會用到SoftReference(使用url做key,bitmap做value的方法),會用到根據手機屏幕來縮放圖片,會及時回收圖片所占用的內存等方法,但說實在的,這些方法治標不治本,圖片該多大還多大,從軟件上我們基本上能做到處理圖片的極限,那么只剩下考慮從硬件來上優化圖片,這就講到了今天所要說的webp。


其中webp不僅僅能應用在Android上,同樣IOS和web端也同樣可以使用。


有關webp的簡介,騰訊同學有詳細介紹,濃縮的精華!從零開始帶你認識最新的圖片格式WEBP我不再多說。


常用的webp轉換工具有:XnConvet智圖ISparta


一張279k的png圖片可以轉換成67.5k的webp圖片,而且不失真


第一步添加webp支持,添加so包和lib包


第二步,添加WebpUtils文件,里面有通過so包來處理webp文件成為byte數組的方法



第三步,應用




效果圖:

你最想要的源碼!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個像素,原圖像素數/(width*height)=壓縮比率^2,得到這個比率后,對原圖進行等比例壓縮;避免的誤區是,以為放入的width*height就是要壓縮到的大小

壓縮像素為1280*720,保證清晰度同比壓縮到,如果超過則取更小值,因此文件大小不能確定,測試兩組數據如下:

原圖長寬     大小   壓縮后長寬      壓縮后大小       長寬比   大小比      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

圖片大小理論值都比實際值要小,可見圖片長寬與大小不成正比;第三組數據和第一組數據共用一台手機,可見同一手機壓縮后的長寬比是一致的。圖片大小壓縮大小最小為5倍;而一般情況下圖片解析得到的Bitmap大小會比文件大5倍左右。

另外頁面中重新定義的ImageView,如果使用當前頁面的context作為引入,則當頁面關閉后可能會引起內存泄露,同時會引起OOM,引用鏈過長同時未被釋放;方法是將Application作為context加入ImageView,在頁面destroy時,清除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();
        }
    }

借這個機會講講避免內存泄露的方法:

Cursor用后及時關閉,Bitmap及對象及時回收,避免在循環體中new對象,注冊的廣播等監聽及時取消,盡量使用Application而非context。


其他內存優化的方法: http://www.diycode.cc/projects/cundong/MemoryMonitor


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM