天天看点

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。