Android 移动开发 | 图形与图像处理--剖析三个绘图工具类--实现Android 机器人绘制案例

1. bitmap图片

Bitmap类

Bitmap类是位图类,在Android负责图像处理的一个类,可以将它看成是一个画架,先把画放到画架上面,然后可以进行一些处理,比如获取图像文件信息,进行图像旋转切割,放大缩小等操作。

Bitmap提供了一些方法,有普通方法和静态方法:

普通方法:

方法 说明
void recycle() 强制回收位图资源
boolean isRecycled() 判断位图内存是否已释放
int getWidth() 获取位图的宽度
int getHeight() 获取位图的高度
boolean isMutable() 图片是否可修改

静态方法:

方法 说明
Bitmap createBitmap(Bitmap src) 以src为原图生成新图像
Bitmap createScaledBitmap(Bitmap src, int dsWidth,int dsHeight,boolean filter) 以src为原图,创建新的图像,指定新图像的高宽以及是否改变
Bitmap createBitmap(int width,int height,Config config) 创建指定宽度与高度的新位图
Bitmap createBitmap(Bitmap source,int x,int y,int width,int height) 以source为原图,指定坐标以及新图像的高宽,挖取一块图像,创建成新的图像
public static Bitmap createBitmap(Bitmap source,int x,int y,int width,int height,Matrix m,boolean filter) 从源位图的指定坐标点开始,挖取指定宽度与高度的一块图像,创建成新的图像

BitmapFactory类

由于Bitmap类的构造函数是私有的,外面并不能实例化。这必然是某个辅助类提供了创建Bitmap的接口,而这个类的实现通过JNI接口来实例化Bitmap的,这个类就是BitmapFactory。
BitmapFactory提供了一些常用的方法如下:

方法 说明
decodeByteArray(byte[] data,int offset,int height) 从指定的字节数组中解码一个不可变的位图
decodeFile(String pathName) 从文件中解码生成一个位图
decodeFileDescriptor(FoleDescriptor fd) 从FileDescriptor文件中解码生成一个位图
decodeResource(Resources res, int id) 根据指定的资源id,从资源中解码位图
decodeStream(InputStream is) 从指定的输入流中解析出位图

2. 绘图常用工具类

2.1 Panit 画笔

Panit 顾名思义即画笔,用于设置绘制风格,如:线宽(笔触粗细),颜色,透明度和填充风格等。

使用语法:
直接使用无参构造方法就可以创建Paint实例:

// 创建一个Paint实例
 Paint paint = new Paint( );

Paint 属性

Paint属性大致上分为:图形绘制属性和文本绘制属性两种

图形绘制属性:

方法 说明
setARGB(int a,int r,int g,int b) 设置绘制的颜色,a表示透明度,r,g,b 表示颜色值。
setAlpha(int a) 设置绘制图形的透明度
setColor(int color) 设置绘制的颜色,使用颜色值来表示,该颜色值包括透明度和RGB颜色
setAntAlias(boolean aa) 设置是否使用锯齿功能,会消耗较大的资源,绘制图形速度较慢
setDither(boolean dither) 设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和·饱满,,图形更加清晰
setFilterBitmap(boolean filter) 如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作, 加快显示速度,本设置项依赖于dither和xfermode的设置
setMaskFilter(MaskFilter maskfilter) 设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等
setColorFilter(ColorFilter colorfilter) 设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果
setPathEffect(PathEffect effect) 设置绘制路径的效果,如点画线等
setShader(Shader shader) 设置图像效果,使用Shader可以绘制出各种渐变效果
setShadowLayer(float radius ,float dx,float dy,int color) 在图形下面设置阴影层,产生阴影效果, radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色
setStyle(Paint.Style style) 设置画笔的样式,为FILL,FILL_OR_STROKE,或STROKE
setStrokeCap(Paint.Cap cap) 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式, 如圆形样Cap.ROUND,或方形样式Cap.SQUARE
setSrokeJoin(Paint.Join join) 设置绘制时各图形的结合方式,如平滑效果等
setStrokeWidth(float width) 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度
setXfermode(Xfermode xfermode) 设置图形重叠时的处理方式,如合并,取交集或并集,经常用来制作橡皮的擦除效果

文本绘制属性:

方法 说明
setFakeBoldText(boolean fakeBoldText) 模拟实现粗体文字,设置在小字体上效果会非常差
setSubpixelText(boolean subpixelText) 设置该项为true,将有助于文本在LCD屏幕上的显示效果
setTextAlign(Paint.Align align) 设置绘制文字的对齐方向
setTextScaleX(float scaleX) 设置绘制文字x轴的缩放比例,可以实现文字的拉伸的效果
setTextSize(float textSize) 设置绘制文字的字号大小
setTextSkewX(float skewX) 设置斜体文字,skewX为倾斜弧度
setTypeface(Typeface typeface) 设置Typeface对象,即字体风格,包括粗体,斜体以及衬线体,非衬线体等
setUnderlineText(boolean underlineText) 设置带有下划线的文字效果
setStrikeThruText(boolean strikeThruText) 设置带有删除线的效果
setStrokeJoin(Paint.Join join) 设置结合处的样子,Miter:结合处为锐角, Round:结合处为圆弧:BEVEL:结合处为直线
setStrokeMiter(float miter) 设置画笔倾斜度
setStrokeCap (Paint.Cap cap) 设置转弯处的风格 其他常用方法:
float ascent( ) 测量baseline之上至字符最高处的距离

2.2 Canvas 画布

Canvas:即画布,就是画画的一块画布,就这简单粗暴的理解哈~

Canvas构造方法

  • Canvas(): 创建一个空画布,使用setBitmap() 来绘制具体的画布
  • Canvas(Bitmap bitmap): 以bitmap对象创建一个画布,将内容都绘制在bitmap上,因此bitmap不得为null。

绘制方法:

drawXXX()方法族

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

其他常用方法:

在这里插入图片描述
save()和restore()要配对使用,restore不能比save多,若restore调用次数比save多,会报错!

2.3 Path 路径

Path:路径即大致框架的点线相连接,在创建好Path路径后,可以调用Canvas的drawPath(path,paint) 将图形绘制出来,路径中常用的方法如下:

  • addArc(RectF oval, float startAngle, float sweepAngle:为路径添加一个多边形
  • addCircle(float x, float y, float radius, Path.Direction dir):给path添加圆圈
  • addOval(RectF oval, Path.Direction dir):添加椭圆形
  • addRect(RectF rect, Path.Direction dir):添加一个区域
  • addRoundRect(RectF rect, float[] radii, Path.Direction dir):添加一个圆角区域
  • isEmpty():判断路径是否为空
  • transform(Matrix matrix):应用矩阵变换
  • (Matrix matrix, Path dst):应用矩阵变换并将结果放到新的路径中,即第二个参数。

PathEffect类的常用方法:

在这里插入图片描述

3. 绘制图像

上面介绍完了三个绘图工具类基本方法,接下来来如何应用工具类中方法来绘制各种图片:
基本步骤:
在绘制图像之前需要先创建一个java类,让其继承自android.view.View类,并为其添加构造方法与重写onDraw方法,绘制图像的代码都要写在onDraw()方法中,从而实绘制图像的实现。
在这里插入图片描述

1、我这里定义一个名为MyView的类继承android.view.View类:
在这里插入图片描述
2、添加构造方法:onDraw()方法并重写onDraw()方法

package com.example.draw;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.View;

public class MyView extends View {
    
    

    public MyRobot(Context context) {
    
    
        super(context);
    }

    // 添加构造方法:onDraw()方法 绘制图像的所有代码都在此方法中实现
    @Override
    protected void onDraw(Canvas canvas) {
    
    
        super.onDraw(canvas);
    }
}

4. 实践| 绘制Android机器人

放上绘制的小demo:绘制Android机器人

  1. 定义一个帧布局管理器,因为图像绘制是一层一层往上画的,所以这个用FramLayout比较好实现。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/framlayout"
    android:layout_width="match_parent"
    android:layout_marginTop="300dp"
    android:layout_marginLeft="150dp"
    android:layout_height="match_parent"
    tools:context=".RobotActivity">

</FrameLayout>
  1. 自定义MyRobot.java类继承android.view.View类,在onDraw() 方法中实现绘制:
package com.example.draw;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.View;

public class MyRobot extends View {
    
    

    public MyRobot(Context context) {
    
    
        super(context);
    }


    @Override
    protected void onDraw(Canvas canvas) {
    
    
        super.onDraw(canvas);
        // 绘制机器人

        Paint paint = new Paint();  // 创建一个画笔
        paint.setAntiAlias(true);   // 抗锯齿 使它更加圆滑
        paint.setColor(0xFFA4C739);

        // 绘制机器人的头
        RectF rectF = new RectF(10,10,100,100); //定义外轮廓矩形
        rectF.offset(90,20);
        canvas.drawArc(rectF,-10,-160,false,paint);  //绘制弧

        // 绘制眼睛
        paint.setColor(0xFFFFFFFF); //设置画笔为白色
        canvas.drawCircle(165,53,4,paint); //绘制圆
        canvas.drawCircle(125,53,4,paint);

        //绘制天线
        paint.setColor(0xFFA4C739);  //设置画笔颜色
        paint.setStrokeWidth(2);  // 设置画笔的宽度
        canvas.drawLine(110,15,125,35,paint); //绘制线
        canvas.drawLine(180,15,165,35,paint); //绘制线

        // 绘制身体
        canvas.drawRect(100,75,190,150,paint);  //绘制矩形
        RectF rectF_body = new RectF(100,140,190,160);
        canvas.drawRoundRect(rectF_body,10,10,paint);  //绘制圆角矩形

        // 绘制胳膊
        RectF rectF_arm = new RectF(75,75,95,140);
        canvas.drawRoundRect(rectF_arm,10,10,paint);  //绘制圆角矩形
        rectF_arm.offset(120,0);
        canvas.drawRoundRect(rectF_arm,10,10,paint);  //绘制圆角矩形

        //绘制腿
        RectF rectF_leg = new RectF(115,150,135,200);
        canvas.drawRoundRect(rectF_leg,10,10,paint);  //绘制圆角矩形
        rectF_leg.offset(40,0);
        canvas.drawRoundRect(rectF_leg,10,10,paint);  //绘制圆角矩形

    }
}

  1. 将自定义的view添加到帧布局管理器中:
package com.example.draw;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.FrameLayout;
import com.example.draw.MyRobot;
public class RobotActivity extends AppCompatActivity {
    
    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_android_robot);
        
        // 获取帧布局管理器
        FrameLayout frameLayout = (FrameLayout) findViewById(R.id.framlayout);
        
        //将自定义的view添加到帧布局布局管理器中
        frameLayout.addView(new MyRobot(this));  
    }
}

学习参考文档:https://developer.android.google.cn/guide/topics/graphics/drawables
学习参考文档:https://www.runoob.com/w3cnote/android-tutorial-intro.html

猜你喜欢

转载自blog.csdn.net/weixin_43853746/article/details/109713557