標籤:
轉載自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)(一)