Android學習之——圖形影像處理(Bitmap、BitmapFactory)(一)

來源:互聯網
上載者:User

標籤:

轉載自http://blog.csdn.net/csxwc/article/details/10345235

Bitmap是Android系統中的影像處理的最重要的類之一。用它可以擷取影像檔資訊,對映像進行旋轉,剪下,放大,縮小等操作。

Bitmap代表一張位元影像,使我們在開發中常用的資源,下面就對Bitmap進行簡單的介紹。

Bitmap的擷取方法:1、使用BitmapDrawableBitmapDrawable裡封裝的圖片就是一個Bitmap對象,我們要把Bitmap封裝成BitmapDrawable對象,可以調用BitmapDrawable的構造方法:BItmapDrawbale drawable = new BItmapDrawable(bitmap);如果要擷取BitmapDrawable所封裝的Bitmap對象,則可調用BitmapDrawable的getBitmap()方法:Bitmap bitmap = drawbale.getBitmap();2、Bitmap提供了一些靜態方法來建立Bitmap對象(僅列舉幾個):
  • createBitmap(Bitmap source,int x,int y,int width,int height):從原位元影像source的指定座標(x,y)開始,從中挖取寬width,高heigtht的一塊出來,建立新的Bitmap對象。
  • createScaledBitmap(Bitmap source,int width,ing height,boolean fliter):對源位元影像進行縮放,縮放稱寬width,高heigth的新位元影像。
  • createBitmap(int width,int height,Bitmap.Config config):建立一個寬width,高height的可變的新位元影像。
  • createBitmap(Bitmap source, int x,int y,int width,int height ,Matrix m,boolean fliter):從源位元影像source的指定座標(x,y)開始,挖取寬width,高height的一塊來,建立新的Bitmap對象,並按照Matrix指定的規則進行變換。
3、通過對資源檔的解析擷取Bitmap對象,在這裡就要用到BitmapFactory這個工具類,提供的方法如下:
  • decodeByteArray(byte[] data, int offset,int length):從指定位元組數組的offset位置開始,將長度為length的位元組資料解析成Bitmap對象。
  • decodeFIle(String pathName):從pathName指定的檔案中解析、建立Bitmap對象。
  • decodeFileDescriptor(FileDescriptor fd):用於從FileDescriptor對應的檔案中解析、建立Bitmap對象。
  • decodeResource(Resource res,int id):用於根據給定的資源ID從指定的資源檔中解析、建立Bitmap對象。
  • decodeStream(InputStream is):用於從指定輸入資料流中介解析、建立Bitmap對象。
但是,在系統不斷的解析、建立Bitmap的過程中,可能會由於記憶體小或其他原因,導致程式運行時發生OutOfMemory錯誤。為此,Android為Bitmap提供了記憶體回收方法:void recycle():強制回收Bitmap對象。還有用於判斷Bitmap 對象是否被回收的方法:boolean isRecycle(); 如果Android應用需要訪問系統相簿,都需要藉助BitmapFactory解析、建立Bitmap對象。點擊開啟連結這篇文章對此略有涉及。 下面是對Bitmap、BitmapFactory的簡單應用。 介紹:對assets目錄下的圖片資源進行查看。由於布局檔案很簡單,在此不給出,源碼如下:

 

public class MainActivity extends Activity {

String[] images = null;
//擷取訪問assets檔案的對象
AssetManager assets = null;
int currentImg = 0;
ImageView img;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

img = (ImageView) findViewById(R.id.img_show);
try {
//擷取訪問assets下檔案的對象
assets = getAssets();
images = assets.list("");
} catch (Exception e) {
e.printStackTrace();
}

Button btn_next = (Button) findViewById(R.id.btn_next);
btn_next.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
//如果角標越界
if(currentImg>=images.length){
currentImg = 0;

}
//找到下一張圖片
while(!images[currentImg].endsWith(".jpg")){
currentImg++;
if(currentImg>=images.length){
currentImg = 0;
}
}
InputStream assetFile = null;

try {
//開啟指定資源對應的輸入資料流
assetFile = assets.open(images[currentImg++]);
} catch (Exception e) {
e.printStackTrace();
}

//回收圖片
BitmapDrawable bitmapDrawable = (BitmapDrawable) img.getDrawable();
if(bitmapDrawable!=null&&!bitmapDrawable.getBitmap().isRecycled()){
bitmapDrawable.getBitmap().recycle();
}

//顯示圖片
img.setImageBitmap(BitmapFactory.decodeStream(assetFile));
}
});
}

另外,在一些遊戲中不斷移動的背景,比如經典的“雷電”飛機遊戲,通過不斷的挖取背景圖片的一部分,給人感官上造成飛機不斷移動的錯覺。可以通過createBitmap(Bitmap bitmap,int x,int y,int width,int height)方法來實現。如下:

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}

class MyView extends View{

//記錄背景位元影像的實際高度
final int BACK_HEIGHT = 1700;
//背景圖片
private Bitmap back;
private Bitmap plane;

//背景圖片的開始位置
final int WIDTH = 320;
final int HEIGHT = 440;

private int startY = BACK_HEIGHT -HEIGHT;

public MyView(Context context) {
super(context);

back = BitmapFactory.decodeResource(context.getResources(), R.drawable.back_img);

plane = BitmapFactory.decodeResource(context.getResources(), R.drawable.plane);

final Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {

if(msg.what ==0x123){
//重新開始移動
if(startY<=0){
startY = BACK_HEIGHT - HEIGHT;
}
else
startY -= 3;
}
invalidate();
}
};
new Timer().schedule(new TimerTask() {

@Override
public void run() {
mHandler.sendEmptyMessage(0x123);
}
}, 0,100);


}
@Override
protected void onDraw(Canvas canvas) {
//根據原始位元影像和Matrix建立新的圖片
Bitmap bitmap_2 = Bitmap.createBitmap(back, 0, startY, WIDTH, HEIGHT);

//繪製新位元影像
canvas.drawBitmap(bitmap_2, 0,0,null);

//繪製飛機
canvas.drawBitmap(plane, 160, 380,null);
}

}

}

//一些圖形效果

Matrix matrix = new Matrix();

//鏡面效果
matrix.setScale(-1, 1);
matrix.postTranslate(bitmap.getWidth(), 0);

//倒影效果
matrix.setScale(1, -1);
matrix.postTranslate(0, bitmap.getHeight());

//圖片合成的效果(android.graphics.PorterDuff.Mode)

//設定重疊部分的效果
paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.DST_ATOP));


canvas.drawBitmap(bitmapa, new Matrix(), paint);

canvas.drawBitmap(bitmapb, new Matrix(),paint);

android.graphics.PorterDuff.Mode的一些取值1.PorterDuff.Mode.CLEAR
所繪製不會提交到畫布上。

2.PorterDuff.Mode.SRC
顯示上層繪製圖片

3.PorterDuff.Mode.DST
顯示下層繪製圖片

4.PorterDuff.Mode.SRC_OVER
正常繪製顯示,上下層繪製疊蓋。

5.PorterDuff.Mode.DST_OVER
上下層都顯示。下層居上顯示。

6.PorterDuff.Mode.SRC_IN
取兩層繪製交集。顯示上層。

7.PorterDuff.Mode.DST_IN
取兩層繪製交集。顯示下層。

8.PorterDuff.Mode.SRC_OUT
取上層繪製非交集部分。

9.PorterDuff.Mode.DST_OUT
取下層繪製非交集部分。

10.PorterDuff.Mode.SRC_ATOP
取下層非交集部分與上層交集部分

11.PorterDuff.Mode.DST_ATOP
取上層非交集部分與下層交集部分

12.PorterDuff.Mode.XOR
取兩層繪製非交集。兩層繪製非交集。

13.PorterDuff.Mode.DARKEN
上下層都顯示。變暗

14.PorterDuff.Mode.LIGHTEN
上下層都顯示。變數

15.PorterDuff.Mode.MULTIPLY
取兩層繪製交集

16.PorterDuff.Mode.SCREEN
上下層都顯示。

Android學習之——圖形影像處理(Bitmap、BitmapFactory)(一)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.