天天看點

Android 圖形圖像處理之一

1、使用簡單圖檔

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回收

Android中為Bitmap提供了兩個提供了兩個方法來判斷他是否已回收,以及強制Bitmap回收自己。

boolean isRecycled() :傳回Bitmap對象是否已被回收

void recycle() :強制回收一個Bitmap對象

圖檔移動縮放:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

public

class

MainActivity 

extends

Activity {

private

ImageView iv;

protected

void

onCreate(Bundle savedInstanceState) {

super

.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

iv = (ImageView) 

this

.findViewById(R.id.iv);

// 設定觸摸監聽事件

iv.setOnTouchListener(

new

MyOnTouchListener());

}

public

final

class

MyOnTouchListener 

implements

OnTouchListener {

private

Matrix mCurrentMatrix = 

new

Matrix();

// 圖檔初始的matrix值

private

Matrix mMatrix = 

new

Matrix();

// 來一個臨時的matrix

private

PointF startPoint = 

new

PointF();

// 初始點

private

PointF midPointF;

// 中心點的位置

private

float

midDistance;

// 兩點之間的距離

private

int

type = 

;

private

final

static

int

DRAG = 

1

;

private

final

static

int

SCALE = 

2

;

public

boolean

onTouch(View v, MotionEvent event) {

int

action = event.getAction() & MotionEvent.ACTION_MASK;

switch

(action) {

case

MotionEvent.ACTION_DOWN:

// 手指按下

float

x = event.getX();

float

y = event.getY();

startPoint.set(x, y);

// 獲得手指按下的初始點

mCurrentMatrix.set(iv.getImageMatrix());

// 圖檔沒有移動的位置

type = DRAG;

break

;

case

MotionEvent.ACTION_POINTER_1_DOWN:

// 螢幕上有一個手指,再按下一根手指

mCurrentMatrix.set(iv.getImageMatrix());

// 圖檔沒有縮放的大小

midPointF = getMidPointF(event);

// 兩個手指獲得中點的坐标

midDistance = getMidDistance(event);

// 獲得兩個手指之間的距離

type = SCALE;

break

;

case

MotionEvent.ACTION_MOVE:

// 螢幕上有一個手指,再按下一根手指

if

(type == DRAG) {

mMatrix.set(mCurrentMatrix);

float

dx = event.getX() - startPoint.x;

float

dy = event.getY() - startPoint.y;

mMatrix.postTranslate(dx, dy);

// 設定圖檔平移,平移的距離為兩個手指移動的距離

else

if

(type == SCALE) {

mMatrix.set(mCurrentMatrix);

float

distance = getMidDistance(event);

// 獲得移動後兩個手指之間的距離

float

sx = distance / midDistance; 

// 用移動後的距離除以移動前的距離,得到移動縮放的比例

mMatrix.postScale(sx, sx, midPointF.x, midPointF.y);

// 對圖檔進行縮放

}

break

;

case

MotionEvent.ACTION_UP:

// 手指彈起

case

MotionEvent.ACTION_POINTER_1_UP:

// 彈起一直手指,你一隻手指彈起

type = 

;

break

;

default

:

break

;

}

iv.setImageMatrix(mMatrix);

return

true

;

}

}

// 計算兩點之間的中點

private

PointF getMidPointF(MotionEvent event) {

float

x = (event.getX(

1

) + event.getX(

)) / 

2

;

float

y = (event.getY(

1

) + event.getY(

)) / 

2

;

return

new

PointF(x, y);

}

// 計算兩點之間的距離

private

float

getMidDistance(MotionEvent event) {

float

dx = event.getX(

1

) - event.getY(

);

float

dy = event.getY(

1

) - event.getY(

);

return

FloatMath.sqrt(dx * dx + dy * dy);

}

}

1 2 3 4 5 6

<

ImageView

android:id

=

"@+id/iv"

android:layout_width

=

"fill_parent"

android:layout_height

=

"fill_parent"

android:scaleType

=

"matrix"

android:src

=

"@drawable/schoolcalendar"

/>

二、Paint類

paint類代表畫筆,用來描述圖形的顔色和風格,如線寬、顔色 、透明度、和填充效果等資訊,使用需要先建立該類的對象,

設定顔色 setColor(int color)

三、Canvas類

Canvas類建立一個畫布

Canvas繪制圖:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

protected

void

onCreate(Bundle savedInstanceState) {

super

.onCreate(savedInstanceState);

// 自定義View

setContentView(

new

MyView(

this

));

}

class

MyView 

extends

View {

Paint mPaint;

public

MyView(Context context) {

super

(context);

// 1、設定畫布

Canvas canvas = 

new

Canvas();

canvas.drawColor(color.white);

// 2、設定畫筆

mPaint = 

new

Paint();

// 設定畫筆的顔色

mPaint.setColor(Color.BLUE);

// 設定畫的透明度

mPaint.setAlpha(

90

);

// 設定畫筆 為空心,stroke為空心

mPaint.setStyle(Paint.Style.STROKE);

}

protected

void

onDraw(Canvas canvas) {

// 畫一個空心正方形 、前兩個為矩形左上角的坐标

canvas.drawRect(

10

80

70

140

, mPaint);

// 畫一個空心圓

canvas.drawCircle(

40

40

30

, mPaint);

}

}

3、使用Matrix控制變換:

​Matrix(矩陣、模型)是Android提供的一個矩陣工具類,它本身并不能對圖像或元件進行變換,但他可對其他API集合來控制圖形、元件的變換。

使用Matrix控制圖像或元件變換的步驟如下:

1、擷取Matrix對象,該Matrix對象既可以新建立,也可以直接擷取其他對象封裝的Matrix

2、調用Matrix的方法進行平移、旋轉、縮放、傾斜等。

3、将程式對Matrix所做的變換應用到指定圖像或元件。

Matrix提供了如下方法來控制平移、旋轉和縮放:

1、Translate————平移變換

2、Scale————縮放變換

3、Rotate————旋轉變換

4、Skew————錯切變換

setTranslate(float dx,floatdy):控制Matrix進行平移

setSkew(float kx,float ky,float px,float py):控制Matrix以px,py為軸心進行傾斜。kx、ky為x,y方向上的傾斜距離。

setSkew(float kx,float ky):控制Matrix進行傾斜。kx、ky為x、y方向上的傾斜距離。

setRotate(float degrees,float px,float py):控制Matrix進行旋轉,degrees控制旋轉的角度。

setRotate(float degrees,float px,float py):設定以px、py為軸心進行旋轉,degrees控制選轉的角度。

set Scale(float sx,float sy):設定Matrix進行縮放,sx,sy控制x,y方向上的縮放比例。

setScale(float sx,float sy,float px,float py):設定Matrix以px、py為軸心進行縮放,sx,sy控制x,y方向上的比例。

一旦對Matrix進行了變換,接下來就可以應用該Matrix對圖像進行控制了。例如Canvas就提供了了一個drawBitmap(Bitmap bitmap,Matrix matrix,Paint paint)方法,調用該方法就可以在繪制bitmap時應用Matrix上的變化。

Matrix,中文裡叫矩陣,高等數學裡有介紹,在圖像處理方面,主要是用于平面的縮放、平移、旋轉等操作。

在Android裡面,Matrix由9個float值構成,是一個3*3的矩陣。最好記住。如下圖:

Android 圖形圖像處理之一

解釋一下,上面的sinX和cosX,表示旋轉角度的cos值和sin值,注意,旋轉角度是按順時針方向計算的。

translateX和translateY表示x和y的平移量。scale是縮放的比例,1是不變,2是表示縮放1/2。