#本文以Android api 22為基準(zhǔn)
10年積累的成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有潛江免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
在android.graphics.PixelFormat中定義了如下幾種(不含deprecated的)RGB格式:
名稱(chēng) | 值 | 含義 |
RGBA_8888 | 1 | 透明通道和三個(gè)顏色通道都是8,可表達(dá)的色彩值最廣,這是使用最廣泛的格式 |
RGBX_8888 | 2 | 與RGBA_8888類(lèi)似不過(guò),透明通道的值永遠(yuǎn)為255 |
RGB_888 | 3 | 只有三個(gè)顏色通道,存儲(chǔ)空間相對(duì)前兩個(gè)較小。 |
Bitmap代表了解碼后圖片,可用于直接的繪制,Bitmap與一個(gè)native層的bitmap對(duì)應(yīng),使用完后,需要調(diào)用recyle函數(shù)回收native內(nèi)存。
android.graphics.Bitmap類(lèi)代表了java層可繪制實(shí)體的最后一步。從一整個(gè)頁(yè)面,到某個(gè)view,在到drawable,最后都會(huì)匯集到Bitmap。
對(duì)于任何一個(gè)view來(lái)說(shuō),在onDraw()回調(diào)中,canvas都已經(jīng)與一個(gè)bitmap綁定。
Bitmap類(lèi)提供了對(duì)像素點(diǎn)操作的一些基本接口。
對(duì)于開(kāi)發(fā)者來(lái)說(shuō),關(guān)于Bitmap需要的做得事情有,創(chuàng)建Bitmap,操作像素,壓縮存儲(chǔ),序列化/反序列化等。
需要自己創(chuàng)建Bitmap時(shí),有兩種情況,一種是全新創(chuàng)建,另外一種是加載已有的圖片。
對(duì)于第一種,可使用Bitmap.createBitmap(...)函數(shù)創(chuàng)建,然后使用Bitmap類(lèi)的像素操作接口填充像素,或者結(jié)合Canvas進(jìn)行更高級(jí)的繪制。
對(duì)于后一種,圖片的來(lái)源無(wú)非是這幾種:network,drawableX目錄,assets目錄,raw目錄,本地持久化存儲(chǔ)。所有的這些圖片都可以通過(guò)android.graphics.BitmapFactory工具類(lèi)加載,解碼并創(chuàng)建為Bitmap。具體如下:
來(lái)源于本地存儲(chǔ) | BitmapFactory.decodeFile(String, Options)或者BitmapFactory.decodeFile(String) |
來(lái)源于drawableX的純圖片 | BitmapDrawable drawable = (BitmapDrawable) context.getDrawable(int picResId); // 注意這里的picResId必須指向一個(gè)純圖片Bitmap bitmap = drawable.getBitmap(); |
來(lái)源于一般的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); |
來(lái)源于assets | 假如圖片路徑為:/assets/img/asset_img.pngBitmap bitmap = BitmapFactory.decodeStream(context.getResources().getAssets().open(“img/asset_img.png")) |
來(lái)源于raw | Bitmap bitmap = BitmapFactory.decodeStream(context.getResources().openRawResource(R.raw.raw_img)) |
操作像素
對(duì)于像素的操作可以通過(guò)Bitmap類(lèi)自己提供的一些基本的操作接口,也可以通過(guò)canvas進(jìn)行。后者提供了很多人性化的繪制方法,并且可以與很多android graphics框架中許多圖形特效類(lèi)結(jié)合使用,繪制出更加出彩的內(nèi)容。這里只談前者,后者會(huì)在其他文章中繼續(xù)討論。
getPixel(int x, int y) | 獲取指定位置的像素色彩值 |
getPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) | 一次獲取多個(gè)像素點(diǎn),如果要獲取多個(gè)像素,調(diào)用此方法比循環(huán)的調(diào)用getPixel()效率要高 |
setPixel(int x, int y) | 設(shè)置指定位置的一個(gè)像素 |
setPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) | 批量設(shè)置像素,對(duì)于同時(shí)設(shè)置多像素來(lái)說(shuō),該方法比循環(huán)調(diào)用setPixel()效率要高 |
copyPixelsToBuffer(Buffer dst) | 復(fù)制整個(gè)圖片像素到一個(gè)buffer |
copyPixelsFromBuffer(Buffer src) | 用一個(gè)buffer中的像素覆蓋當(dāng)前bitmap中的像素 |
setPixels()和getPixels()參數(shù)中的stride代表了參數(shù)pixels一行的長(zhǎng)度,我們可以把這兩個(gè)方法看作是一個(gè)像素矩陣向另外一個(gè)像素矩陣投射的過(guò)程,兩個(gè)矩陣可能大小不同。不管是setPixels()還是getPixels(),當(dāng)位圖像素的讀取或設(shè)置需要換行時(shí),pixels數(shù)組也需要”換行”,這時(shí)后者的換行就需要以stride為基準(zhǔn)。這也是為甚stride要大于等于width的原因。具體可以看這篇文章:http://ranlic.iteye.com/blog/1313735
壓縮存儲(chǔ)
Bitmap.compress(CompressFormat format, int quality, OutputStream outStream),其中quality的值范圍是[0, 100],0代表最低的質(zhì)量最大的壓縮。
序列化與反序列化
Bitmap實(shí)現(xiàn)了Parcelable接口,如果是用intnet進(jìn)行數(shù)據(jù)傳遞,可以直接放到extra中。
如果是通過(guò)網(wǎng)絡(luò)傳輸(這里不考慮需求的合理性,因?yàn)閷?shí)際中很少有直接通過(guò)網(wǎng)絡(luò)傳輸位圖的,都是傳輸壓縮后的圖片),則需要調(diào)用copyPixelsToBuffer()。