Android應用開發之圖片(Bitmap)壓縮(三)---------採樣率壓縮

博客爲 有時個哥 原創,如需轉載請標明出處:http://blog.csdn.net/ls703/article/details/40617465

採樣率壓縮:

採樣率壓縮是改變了圖片的像素,他是通過先讀取圖片的邊,然後在自己設定圖片的邊,然後根據設定,讀取圖片的像素。在讀取的時候,並不是所有的像素都讀取,而是由選擇的。所以這種方式減少了像素的個數,能改變圖片在內存中的佔用大小。大體的用法如下面。我們用下面的簡單實例代碼來了解一下。

package com.example.bitmapdemo.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.text.TextUtils;

public class ImageUtils3 {
	
	public static Bitmap compressImageToBitmap(String imagePath){
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeFile(imagePath,options);
		if(bitmap != null){
			System.out.println("bitmap=========1>>>>"+bitmap.getByteCount());
		}else{
			System.out.println("kong");
		}
		options.inJustDecodeBounds = false;
		options.inSampleSize = 2;
		
		bitmap = BitmapFactory.decodeFile(imagePath,options);
		System.out.println("bitmap=========2>>>>"+bitmap.getByteCount());
		
		return bitmap;
	}
	
}


 

package com.example.bitmapdemo;

import java.io.FileInputStream;

import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Environment;

import com.example.bitmapdemo.utils.ImageUtils;
import com.example.bitmapdemo.utils.ImageUtils2;
import com.example.bitmapdemo.utils.ImageUtils3;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
//		String imagePath = "/mnt/sdcard/image.png";
		String imagePath = "/mnt/sdcard/17.jpg";
		Bitmap bitmap = getBitmap(imagePath);
		getInputStreanm(imagePath);
//		getCompessImage(imagePath);
		getCompessImage(bitmap);
//		getCompess(imagePath);
		
	}

	public Bitmap getBitmap(String pathName){
		Bitmap bm = ImageUtils.getBitmapFromLocal(pathName);
//		Bitmap bm = ImageUtils2.getBitmapFromLocal(pathName);
//		System.out.println("bitmap:::"+bm.getRowBytes()*bm.getHeight());
		System.out.println("bitmap:::"+bm.getByteCount());
		System.out.println("bitmap的另一種求法:::"+bm.getWidth() * bm.getHeight()*4 ); 
		return bm;
	}
	
	public void getInputStreanm(String pathName){
		try {
			FileInputStream fis = new FileInputStream(pathName);
			System.out.println("inputStream:::"+fis.available());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void getCompess(String pathName){
		ImageUtils2.writeCompressImage2File(pathName,Environment.getExternalStorageDirectory()
				.getAbsolutePath()+"/oo", 60);
	}
	public void getCompessImage(String pathName){
		ImageUtils3.compressImageToBitmap(pathName);
	}
	public void getCompessImage(Bitmap bitmap){
		ImageUtils3.compressImageToBitmap(bitmap);
	}
}

然後下面是運行結果:

由運行結果我們可以看出前後的bitmap唄壓縮了4倍。關於ImageUtils3中的BitmapFactory裏面的一些方法的作用已經在Android應用開發之圖片(Bitmap)壓縮(一)中介紹過了。

options.inJustDecodeBounds = true;這一句話是允許讀取圖片的邊,然後讀取Bitmap bitmap = BitmapFactory.decodeFile(imagePath,options);圖片,把圖片的信息存入到了上面BitmapFactory.Options options = new BitmapFactory.Options();的options裏面了。值得注意的是,當options.inJustDecodeBounds 的值是true,只是讀取圖片的邊,而不是讀取整個圖片,所以Bitmap bitmap = BitmapFactory.decodeFile(imagePath,options);得到的bitmap是空的。獲得圖片的信息後,接下來爲了能保證獲得正常的bitmap,所以要關閉 options.inJustDecodeBounds ,即把他的值變爲false;然後我們在根據自己的需求設置圖片的大小。options.inSampleSize 這個參數就是來設置圖片的壓縮倍數,我這裏測試時寫的值是2,也就是說是原來的1/2,要注意,這裏的1/2值得是寬和高分別是原圖的1/2。所以圖片是被壓縮了四倍,從輸出的結果我們也能看出。這裏也可以通過options得到圖片的高和寬,用高寬,來設定壓縮的倍數。設置好壓縮的倍數,則在運行Bitmap bitmap = BitmapFactory.decodeFile(imagePath,options);獲得bitmap。由於此時options.inJustDecodeBounds = false,所以是得到的bitmap不是空了,此時得到是已經壓縮好的bitmap。

 

採樣率壓縮,的的確確的改變了圖片佔用內存問題,但是由於像素改變,壓縮容易造成失真問題。使用採樣率壓縮,不需要一開始把圖片完全讀取到內存,而是先讀取圖片的邊,然後設置圖片的尺寸,然後再根據尺寸,選擇的讀取像素。這種方法避免了一開始就吧圖片讀入內存而造成的oom異常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章