Android移动开发--对图形图像处理的介绍与应用

前言

随着移动设备的不断普及与发展,相关的软件开发技术也越来越受到人们所重视。Android作为全球最受欢迎的移动智能终端平台。图形图像处理技术在Android中非常重要,特别是在开发益智类游戏或者2D游戏时都离不开图形图像处理技术。在绘制图像时最常用的就是Bitmap类、BitmapFactory类、Paint类、Canvas类和Matrix类。其中,Bitmap类代表位图,BitmapFactory类顾名思义就是位图工厂,它是一个工具类,Paint类代表画笔,Canvas类代表画布,为图片添加特效使用的是Matrix类。接下来给大家针对图形图像处理的API进行讲解和具体应用

1.Bitmap类

Bitmap类是Android系统中非常重要的图像处理类。它提供了一系列的方法,可对图像进行旋转、缩放等操作,并可以指定格式保存图像文件。对于这些操作,都可以通过Bitmap类提供的方法来实现。Bitmap类提供的常用方法如下表所示

方法名称 功能描述
createBitmap(int width, int height, Config config) 创建位图,width代表要创建的图片的宽度,height代表高度,config代表图片的配置信息
createBitmap(int colors[], int offset, int stride, int width,i nt height, Config config) 使用颜色数组创建一个指定宽高的位图,颜色数组的个数为width*height
createBitmap(Bitmap src) 使用源位图创建一个新的Bitmap
createBitmap(Bitmap source, int x, int y, int width, int height) 从源位图的指定坐标开始“挖取”指定宽高的一块图像来创建新的Bitmap对象
createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter) 从源位图的指定坐标开始“挖取”指定宽高的一块图像来创建新的Bitmap对象,并按照Matrix规则进行变换
isRecycle() 判断Bitmap对象是否被回收
recycle() 回收Bitmap对象

创建一个Bitmap对象的示例代码:

Bitmap.Config config = Config.ARGB_4444;
Bitmap bitmap = Bitmap.createBitmap(width, height, config);

Config是Bitmap的内部类,用于指定Bitmap的一些配置信息,这里的Config.ARGB_4444意思为Bitmap的每个像素点占用内存2个字节。

2.BitmapFactory类

BitmapFactory类是一个工具类,主要用于从不同的数据源(如文件、数据流和字节数组)来解析、创建Bitmap对象。BitmapFactory类提供的常用方法如下表所示。

方法名称 功能描述
decodeFile(String pathName) 从指定文件中解析、创建Bitmap对象
decodeStream(InputStream is) 从指定输入流中解析、创建Bitmap对象
decodeResource(Resources res, int id) 根据给定的资源id,从指定资源中解析、创建Bitmap对象

解析SD卡中的图片文件,并创建对应Bitmap对象的示例代码:

Bitmap bitmap = BitmapFactory.decodeFile(“图片地址”);

同时也可以解析Drawable文件夹中的图片文件,并创建相应的Bitmap对象的示例代码

Bitmap bitmap = BitmapFactory.decodeResource(getResource(), R.drawable.ic_launcher);

3.Paint类

Paint类代表画笔,用来描述图形的颜色和风格,如线宽、颜色、透明度和填充效果等信息。使用Paint类时,首先要创建他它的示例对象,然后通过该类提供的方法来更改Paint对象的默认设置。类Paint提供的常用方法如下表所示

方法名称 功能描述
Paint() 创建一个Paint对象,并使用默认属性
Paint(int flags) 创建一个Paint对象,并使用指定属性
setARGB(int a, int r, int g, int b) 设置颜色,各参数值均为0~255之间的整数,几个参数分别用于表示透明度、红色、绿色和蓝色值
setColor(int color) 设置颜色
setAlpha(int a) 设置透明度
setAntiAlias(boolean aa) 指定是否使用抗锯齿功能,如果使用会使绘图速度变慢
setDither(boolean dither) 指定是否使用图像抖动处理,如果使用会使图像颜色更加平滑、饱满,清晰
setShadowLayer(float radius, float dx, float dy, int color) 设置阴影,参数radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色。
setTextAlign(Align align) 设置绘制文本时的文字对齐方式,参数值为Align.CENTER、Align.LEFT或Align.RIGHT
setTextSize(float textSize) 设置绘制文本时的文字大小
setFakeBoldText(boolean fakeBoldText) 设置绘制文本时是否为粗体文字
setXfermode(Xfermode xfermode) 设置图形重叠时的处理方式,例如合并、取交集或并集,经常用来制作橡皮的擦除效果

Paint类代表画笔,在绘制图像时,避免不了要使用画笔,因此掌握Paint类的常用方法及使用是很有必要的。通过一段示例代码定义一个画笔,并指定该画笔的颜色为红色:

Paint paint = new Paint();
paint.setColor(Color.RED);

4.Canvas类

Canvas类代表画布,通过使用该类提供的方法,可以绘制各种图形(如矩形、圆形、线条等)。类Canvas提供的常用方法如下表所示

方法名称 功能描述
drawRect(Rect r,Paint paint) 使用画笔画出指定矩形
drawOval(RectF oval,Paint paint 使用画笔画出指定椭圆
drawCircle(float cx,float cy,float radius,Paint paint) 使用画笔在指定位置画出指定半径的圆
drawLine(float startX,float startY,float stopX,float stopY,Paint paint) 使用画笔在指定位置画线
drawRoundRect(RectF rect,float rx,float ry,Paint paint) 使用画笔绘制指定圆角矩形,其中rx表示x轴圆角半径,ry表示y轴圆角半径

通过一段示例代码来演示如何使用画布绘制矩形。需要注意的是,Canvas类在创建时需要继承view类,并在该类中重写onDraw()方法:

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint=new Paint(); //创建画笔
paint.setColor(Color.RED); //设置颜色为红色
Rect r = new Rect(40,40,200,100);//构建矩形对象并为其指定位置、宽高
canvas.drawRect(r.paint); //调用Canvas中绘制矩形的方法
}

5.Matrix类

Android提供了Matrix类,使用该类提供的方法,可以对图片添加特别的效果,如旋转,缩放,倾斜,平移等。Matrix类常用的一些方法如下表

方法名称 功能描述
Matrix() 创建一个唯一的Matrix对象
setRotate(float degrees) 将Matrix对象围绕(0,0)旋转degrees度
setRotate(float degrees,float px,float py) 将Matrix对象围绕(px,py)旋转degrees度
setScale(float sx,float sy) 对Maria对象进行缩放,参数sx代表x轴上的缩放比例,sy代表y轴上的缩放比例
setScale(float sx,float sy,float px,float py) 让Matrix对象以(px,py)为轴心,在x轴上缩放sx,在y轴上缩放sy
setSkew(float kx,float ky) 让Matrix对象倾斜,在x轴上倾斜kx,在y轴上倾斜ky
setSkew(float kx,float ky,float px,float py) 让Matrix对象以(px,py)为轴心,在x轴上倾斜kx,在y轴上倾斜ky
setTranslate(float dx,float dy) 平移Matrix对象,(dx,dy)为Matrix平移后的坐标

为了更好掌握方法的使用,通过一段示例代码为图片添加旋转特效:

Matrix matrix = new Matrix();//创建Matrix对象
matrix.setRotate(30);//设置Matrix旋转30度

6.具体应用为图形添加特效

一:旋转图像

使用Android提供的android.graphics.Matrix类的setRotate(float degrees)方法对图像进行旋转。在MainActivity中创建名为MyView的内部类,刚刚强调到在创建Canvas类时需要继承View类,并添加构造方法和重写onDraw(Canvas canvas)方,在里面进行作图:
首先定义一个画笔,绘制一张背景图像,然后在(0,0)点的位置绘制要旋转图像的原图,再绘制以(0,0)点为轴心旋转30度的图像
背景图像和原图放在res\drawable的目录下:


继承view类的函数:包括重写onDraw(Canvas canvas)方法:

public class MyView extends View{ public MyView(Context context) { super(context); // TODO Auto-generated constructor stub } @Override protected void onDraw(Canvas canvas) { Paint paint=new Paint();//定义一个画笔 Bitmap bitmap=BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.background); canvas.drawBitmap(bitmap, 0, 0, paint);//绘制背景图像 Bitmap bitmap_img1=BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.img); canvas.drawBitmap(bitmap_img1, 0, 0, paint);//绘制原图 //应用setRotate(float degress)方法旋转图像 Matrix matrix=new Matrix(); matrix.setRotate(30);//以(0,0)点为轴心旋转30度 canvas.drawBitmap(bitmap_img1, matrix, paint);//绘制变化后的图像 super.onDraw(canvas); } } 

得到的效果图:

二:缩放图像

使用Android提供的android.graphics.Matrix类的setScale(float sx,float sy)方法对图像进行缩放,sx代表x轴上的缩放比例,sy代表y轴上的缩放比例。方法与旋转时的实现方式差不多。
首先定义一个画笔,绘制一张背景图像,然后在(0,0)点的位置绘制要旋转图像的原图,再绘制以(0,0)点为轴心,在X轴和Y轴上均缩放50%的图像

@Override protected void onDraw(Canvas canvas) { Paint paint=new Paint();//定义一个画笔 Bitmap bitmap=BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.background); canvas.drawBitmap(bitmap, 0, 0, paint);//绘制背景图像 Bitmap bitmap_img1=BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.img); canvas.drawBitmap(bitmap_img1, 0, 0, paint);//绘制原图 //应用setRotate(float degress)方法旋转图像 Matrix matrix=new Matrix(); matrix.setScale(0.5f, 0.5f);//以(0,0)点为轴心在X轴和Y轴上均缩放50% canvas.drawBitmap(bitmap_img1, matrix, paint);//绘制图像并应用matrix的变换 super.onDraw(canvas); } 

得到的效果图:

三:倾斜图像

使用Android提供的android.graphics.Matrix类的setSkew(float kx,float ky)方法,可以对图像进行缩放。在x轴上倾斜kx,在y轴上倾斜ky
首先定义一个画笔,绘制一张背景图像,然后在(0,0)点的位置绘制要旋转图像的原图,再绘制以(0,0)点为轴心,在X轴上倾斜2,在y轴上倾斜3

@Override protected void onDraw(Canvas canvas) { Paint paint=new Paint();//定义一个画笔 Bitmap bitmap=BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.background); canvas.drawBitmap(bitmap, 0, 0, paint);//绘制背景图像 Bitmap bitmap_img1=BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.img); canvas.drawBitmap(bitmap_img1, 0, 0, paint);//绘制原图 //应用setRotate(float degress)方法旋转图像 Matrix matrix=new Matrix(); matrix.setSkew(2f, 3f);//以(0,0)点为轴心在X轴上倾斜2,在y轴上倾斜3 canvas.drawBitmap(bitmap_img1, matrix, paint);//绘制图像并应用matrix的变换 super.onDraw(canvas); } 

得到的效果图:

四:平移图像

使用Android提供的android.graphics.Matrix类的setTranslate(float dx,float dy)方法,可对图像进行平移。(dx , dy)为Matrix平移后的坐标
首先定义一个画笔,绘制一张背景图像,然后在(0,0)点的位置绘制要旋转图像的原图,平移图像,在(50,50)的地方绘制平移后的图像

@Override protected void onDraw(Canvas canvas) { Paint paint=new Paint();//定义一个画笔 Bitmap bitmap=BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.background); canvas.drawBitmap(bitmap, 0, 0, paint);//绘制背景图像 Bitmap bitmap_img1=BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.img); canvas.drawBitmap(bitmap_img1, 0, 0, paint);//绘制原图 //应用setRotate(float degress)方法旋转图像 Matrix matrix=new Matrix(); matrix.setTranslate(50, 50);//平移到坐标(50,50) canvas.drawBitmap(bitmap_img1, matrix, paint);//绘制图像并应用matrix的变换 super.onDraw(canvas); } 

得到的效果图:

五:刮刮乐应用程序:

首先我们先明白刮刮乐的设计思路。在布局文件中添加两个ImageView,分别为刮奖图和中奖图。将中奖图作为app的背景,先从资源文件中解析一张Bitmap即面向用户的刮奖图。创建画笔对象,Matrix对象绘制刮奖图。为imageView设置触摸监听,当手指触摸到ImageView时,调用setPixel(int x,int y,@ColorInt int color)方法将区域类的像素点设置为透明像素,这时背景图(中奖图)就会呈现在用户面前
布局文件activity_main.xml的编写 添加两个ImageView(编写较为简单,这边简单列出代码):

<ImageView android:id="@+id/bg" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg"/> <ImageView android:id="@+id/imgv" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/scratch_card" /> 

接下来编写界面交互代码:
解析刮奖图的Bitmap

Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.scratch_card);
alterBitmap = Bitmap.createBitmap(bitmap.getWidth(),itmap.getHeight(), bitmap.getConfig());

绘制刮奖图:

Canvas canvas = new Canvas(alterbitmap);//创建一个Canvas对象
Paint paint = new Paint();//创建画笔对象
paint.setColor(Color.BLACK);//为画笔设置颜色
paint.setAntiAlias(true)
Matrix matrix = new Matrix();
canvas.drawBitmap(bitmap, matrix, paint);//绘制图像

为ImageView设置触摸监听

imageView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { try { int x = (int) event.getX(); int y = (int) event.getY(); for (int i = -100; i < 100; i++) { for (int j = -100; j < 100; j++) { //将区域类的像素点设为透明像素 if (Math.sqrt((i * i) + (j * j)) <= 100) { alterbitmap.setPixel((int) (x * nX) + i, (int) (y * nY+90) + j, Color.TRANSPARENT); } } } imageView.setImageBitmap(alterbitmap); } catch (Exception e) { //加try{}catch(){}放置用户触摸图片以外的地方而异常退出 e.printStackTrace(); } //销毁掉该触摸事件 return true; } }) 

运行截图:首先得到刮奖界面:

手指所到之处像素会变透明,从而显示ImageView的背景即中奖信息:

作者:林钰
原文链接