關於bitmap你不知道的一些事
1、計算機表示圖形的幾種方式
1)BMP :幾乎不進行壓縮 佔用空間比較大
2)JPG : 在BMP的基礎上對相鄰的畫素進行壓縮,佔用空間比BMP小
3) PNG : 在JPG的基礎上進一步壓縮 佔用空間比較小
這是對三種格式進行一個簡單的介紹,知道是怎麼回事就行,在android中一般都用png格式的圖片,因為他佔用空間小
2、圖形的大小
圖形的大小 = 圖片的總畫素*每個畫素的大小
圖片總畫素 = 圖片的長*圖片的高
可以看到 儲存一張圖片時有一些選項看一下其中幾個
單色點陣圖: 每個畫素最多可以表示2種顏色,只需要使用長度為1的二進位制位來表示,因此每個畫素佔1/8byte
16色點陣圖: 每個畫素最多可以表示16種顏色,所以只需要長度為4的二進位制表示,因此每個畫素佔1/2byte
256色點陣圖: 每個畫素最多可以表示256中顏色,所以只需要長度是8的二級制位表示就可以了,因此每個畫素佔1byte
24位點陣圖:即RGB三原色點陣圖 每個畫素佔3個byte。
3、android 載入大圖失敗的原因
知道了上面的知識後,來研究一下android 當中的點陣圖資訊,
在android 中採用ARGB來表示顏色,所以每個畫素會佔4byte。
當用BitmapFactory載入原圖時當圖片的寬和高遠大於手機的寬和高時會出現
E/AndroidRuntime(2128): Caused by: java.lang.OutOfMemoryError
E/dalvikvm-heap(2128): Out of memory on a 30720012-byte allocation.
也就是記憶體越界異常,但是看圖片的大小並沒有超過系統所分給每個應用的記憶體大小。
所以可以確定 載入原圖時圖片的計算方式是按上面的公式計算的。
4、載入大圖的方法
知道了載入大圖失敗的原因後,解決OutOfMemoryError的方法也就很明顯了,對的 就是縮放。
下面就看看下縮放的步驟
1) 獲取手機的寬和高
2)獲取圖片的寬和高
3)計算縮放比
4)按照縮放比顯示圖片
//1) 獲取手機的寬和高
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
int screenWidth = wm.getDefaultDisplay().getWidth();
int screenHeight = wm.getDefaultDisplay ().getHeight();
//2)獲取圖片的寬和高
BitmapFactory.Options options = new Options();
//返回一個null 沒有bitmap,不去真正解析點陣圖,但是能返回圖片的一些資訊。
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.drawable.dog,options);
int imagWidth = options.outWidth;
int imagHeight = options.outHeight;
//3)計算縮放比
int scale =1;
int scalex = imagWidth / screenWidth;
int scaley = imagHeight / screenHeight;
scale = Math.max(scalex, scaley);
//4)按照縮放比顯示圖片
options.inSampleSize = scale;
//開始真正的解析點陣圖
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dog,options);
5、Bitmap修改圖片
在看一種情況,當用BitmapFactory.decodeXXX decode一張圖片後,需要修改圖片
如:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
bitmap.setPixel(100, 20, Color.RED);
發現push到手機後報錯了,這是因為原圖是不能被修改的。
那麼當需要修改圖片是怎麼辦呢?
對了 可以操作原圖的副本,副本是可以修改的
建立原圖的副本步驟如下:
1)建立模板
2)建立一個畫布以原圖作為模板
3)建立一個畫筆
4)開始拷貝原圖
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
// bitmap.setPixel(100, 20, Color.RED);
// 1)建立模板
Bitmap copybitmap = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), bitmap.getConfig());
// 2)建立一個畫布以原圖作為模板
Canvas canvas = new Canvas(copybitmap);
// 3)建立一個畫筆
Paint paint = new Paint();
// 4)開始拷貝原圖
canvas.drawBitmap(bitmap, new Matrix(), paint);
// 修改圖片
copybitmap.setPixel(20, 30, Color.RED);
至此是我工作中發現的一些小的細節,別的一些操作點陣圖的方法應該都是大家所熟知的了,就不再班門弄斧了