Bitmap是Android系統(tǒng)中的圖像處理的最重要類之一。用它可以獲取圖像文件信息,進行圖像剪切毡泻、旋轉(zhuǎn)、縮放等操作粘优,并可以指定格式保存圖像文件仇味。
Bitmap BitmapFactory 簡介
Bitmap類的構(gòu)造方法都是私有的,開發(fā)者不能直接new出一個Bitmap對象雹顺,只能通過BitmapFactory類的各種靜態(tài)方法來實例化一個Bitmap丹墨。
Bitmap bitmap = BitmapFactory.decodeFile(String pathName);
Bitmap bitmap = BitmapFactory.decodeFile(String pathName, Options opts);
Bitmap bitmap = BitmapFactory.decodeResource(Resources res, int id);
Bitmap bitmap = BitmapFactory.decodeResource(Resources res, int id, Options opts);
Bitmap bitmap = BitmapFactory.decodeStream(InputStream is);
Bitmap bitmap = BitmapFactory.decodeStream(InputStream is, Rect outPadding, Options, opts);
這樣就得到一個Bitmap。android讀取Bitmap位圖時嬉愧,如果圖片超出虛擬機分配給的內(nèi)存大小贩挣,就會報OOM~,所以在操作Bitmap時要用好recycle() 方法没酣。
如上已知Bitmap 時通過 BitmapFactory 生成王财。其實通過源碼可知,生成Bitmap對象最終都是通過JNI調(diào)用方式實現(xiàn)的裕便。所以绒净,加載Bitmap到內(nèi)存里以后,是包含兩部分內(nèi)存區(qū)域的偿衰。簡單的說挂疆,一部分是Java部分的,一部分是C部分的哎垦。這個Bitmap對象是由Java部分分配的囱嫩,不用的時候系統(tǒng)就會自動回收了,但是那個對應的C可用的內(nèi)存區(qū)域漏设,虛擬機是不能直接回收的,這個只能調(diào)用底層的功能釋放今妄。所以需要調(diào)用recycle()方法來釋放C部分的內(nèi)存郑口。從Bitmap類的源代碼也可以看到,recycle()方法里也的確是調(diào)用了JNI方法了盾鳞。
Options
decode 時有個 options 的參數(shù)犬性。利用Options選項的一些屬性,可以對Bitmap簡單的操作
- inSampleSize:縮小圖片腾仅。表示縮略圖大小為原始圖片大小的幾分之一乒裆。即如果這個值為2,則取出的縮略圖的寬和高都是原始圖片的1/2推励,圖片的大小就為原始大小的1/4
- inJustDecodeBounds:為true后鹤耍,再使用decodeFile()等方法肉迫,并不會真正的分配空間,即解碼出來的Bitmap為null稿黄,但是可計算出原始圖片的寬度和高度喊衫,即 options.outWidth 和options.outHeight。通過這兩個值杆怕,就可以知道圖片是否過大
- inPreferredConfig:指定decode到內(nèi)存中族购,手機中所采用的編碼,可選值定義在Bitmap.Config中陵珍。缺省值是ARGB_8888
應用
保存Bitmap到本地
public static File saveImage(Bitmap bmp) {
File appDir = new File(Environment.getExternalStorageDirectory(), "Boohee");
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = System.currentTimeMillis() + ".jpg";
File file = new File(appDir, fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
bmp.compress(CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
主要用的 Bitmap 的 compress() 方法
第一個參數(shù) :圖片格式JPEG或PNG
第二個參數(shù):壓縮質(zhì)量 0-100之間
第三個參數(shù):輸出流
網(wǎng)絡(luò)獲取圖片顯示
public Bitmap returnBitMap(String url){
URL myFileUrl = null;
Bitmap bitmap = null;
try {
myFileUrl = new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection conn = (HttpURLConnection) myFileUrl
.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
主要使用的時 Bitmap 的 decodeStream() 方法寝杖。
Drawable轉(zhuǎn)Bitmap
//第一種方式
public static Bitmap drawableToBitmap(Drawable drawable) {
int w = drawable.getIntrinsicWidth();
int h = drawable.getIntrinsicHeight();
System.out.println("Drawable轉(zhuǎn)Bitmap");
Bitmap.Config config =
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565;
Bitmap bitmap = Bitmap.createBitmap(w, h, config);
//注意,下面三行代碼要用到互纯,否則在View或者SurfaceView里的canvas.drawBitmap會看不到圖
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, w, h);
drawable.draw(canvas);
return bitmap;
}
//第二種方式
public static Bitmap drawableToBitmap(Drawable drawable) {
BitmapDrawable bd = (BitmapDrawable) drawable;
Bitmap bitmap = bd.getBitmap();
return bitmap;
}
Bitmap 轉(zhuǎn)換成 Drawable
Drawable drawable = new BitmapDrawable(bmp);
Bitmap 轉(zhuǎn)換成 byte[]
public static byte[] getBytes(Bitmap bitmap){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
return baos.toByteArray();
}
byte[] 轉(zhuǎn)化成 Bitmap
public static Bitmap Bytes2Bimap(byte[] b) {
if (b.length != 0) {
return BitmapFactory.decodeByteArray(b, 0, b.length);
} else {
return null;
}
}
優(yōu)化
優(yōu)化主要是 Bitmap 顯示圖片的 三級緩存 優(yōu)化朝墩,詳見個人博客 Android 圖片三級緩存~