#本文以Android api 22為基準
在android.graphics.PixelFormat中定義了如下幾種(不含deprecated的)RGB格式:
名稱 | 值 | 含義 |
RGBA_8888 | 1 | 透明通道和三個顏色通道都是8,可表達的色彩值最廣,這是使用最廣泛的格式 |
RGBX_8888 | 2 | 與RGBA_8888類似不過,透明通道的值永遠為255 |
RGB_888 | 3 | 只有三個顏色通道,存儲空間相對前兩個較小。 |
Bitmap代表了解碼后圖片,可用于直接的繪制,Bitmap與一個native層的bitmap對應,使用完后,需要調用recyle函數回收native內存。
android.graphics.Bitmap類代表了java層可繪制實體的最后一步。從一整個頁面,到某個view,在到drawable,最后都會匯集到Bitmap。
對于任何一個view來說,在onDraw()回調中,canvas都已經與一個bitmap綁定。
Bitmap類提供了對像素點操作的一些基本接口。
對于開發者來說,關于Bitmap需要的做得事情有,創建Bitmap,操作像素,壓縮存儲,序列化/反序列化等。
需要自己創建Bitmap時,有兩種情況,一種是全新創建,另外一種是加載已有的圖片。
對于第一種,可使用Bitmap.createBitmap(...)函數創建,然后使用Bitmap類的像素操作接口填充像素,或者結合Canvas進行更高級的繪制。
對于后一種,圖片的來源無非是這幾種:network,drawableX目錄,assets目錄,raw目錄,本地持久化存儲。所有的這些圖片都可以通過android.graphics.BitmapFactory工具類加載,解碼并創建為Bitmap。具體如下:
來源于本地存儲 | BitmapFactory.decodeFile(String, Options)或者BitmapFactory.decodeFile(String) |
來源于drawableX的純圖片 | BitmapDrawable drawable = (BitmapDrawable) context.getDrawable(int picResId); // 注意這里的picResId必須指向一個純圖片Bitmap bitmap = drawable.getBitmap(); |
來源于一般的drawable | Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), config);Canvas canvas = new Canvas(bitmap);drawable.setBounds(0, 0, w, h);drawable.draw(canvas); |
來源于assets | 假如圖片路徑為:/assets/img/asset_img.pngBitmap bitmap = BitmapFactory.decodeStream(context.getResources().getAssets().open(“img/asset_img.png")) |
來源于raw | Bitmap bitmap = BitmapFactory.decodeStream(context.getResources().openRawResource(R.raw.raw_img)) |
操作像素
對于像素的操作可以通過Bitmap類自己提供的一些基本的操作接口,也可以通過canvas進行。后者提供了很多人性化的繪制方法,并且可以與很多android graphics框架中許多圖形特效類結合使用,繪制出更加出彩的內容。這里只談前者,后者會在其他文章中繼續討論。
getPixel(int x, int y) | 獲取指定位置的像素色彩值 |
getPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) | 一次獲取多個像素點,如果要獲取多個像素,調用此方法比循環的調用getPixel()效率要高 |
setPixel(int x, int y) | 設置指定位置的一個像素 |
setPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) | 批量設置像素,對于同時設置多像素來說,該方法比循環調用setPixel()效率要高 |
copyPixelsToBuffer(Buffer dst) | 復制整個圖片像素到一個buffer |
copyPixelsFromBuffer(Buffer src) | 用一個buffer中的像素覆蓋當前bitmap中的像素 |
setPixels()和getPixels()參數中的stride代表了參數pixels一行的長度,我們可以把這兩個方法看作是一個像素矩陣向另外一個像素矩陣投射的過程,兩個矩陣可能大小不同。不管是setPixels()還是getPixels(),當位圖像素的讀取或設置需要換行時,pixels數組也需要”換行”,這時后者的換行就需要以stride為基準。這也是為甚stride要大于等于width的原因。具體可以看這篇文章:http://ranlic.iteye.com/blog/1313735
壓縮存儲
Bitmap.compress(CompressFormat format, int quality, OutputStream outStream),其中quality的值范圍是[0, 100],0代表最低的質量最大的壓縮。
序列化與反序列化
Bitmap實現了Parcelable接口,如果是用intnet進行數據傳遞,可以直接放到extra中。
如果是通過網絡傳輸(這里不考慮需求的合理性,因為實際中很少有直接通過網絡傳輸位圖的,都是傳輸壓縮后的圖片),則需要調用copyPixelsToBuffer()。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。