android 中的绘制类Paint 画笔,Canvas 画布,Bitmap 类和BitmapFactory及自定义属性

常用的绘图类是Paint 画笔,Canvas 画布,Bitmap 类和BitmapFactory

Paint类

Paint类代表画笔,用来描述图形的颜色和风格,如线宽,颜色,透明度,和填充效果等信
息,使用Paint时,需要先创建该类的对象,这可以通过该类提供的构造方法来实现。通常情
况下,只需要使用无参数的构造方法来创建一个使用默认设置的Paint对象:

 Panit paint=new Panint()

常用方法

 setARGB(int a, int r, int g, int b)
 用于设置颜色,各参数值均为0~255之间的整数,分别用于表示透明度、红色、绿色和蓝色值

 setColor(int color)
 用于设置颜色,参数color可以通过Color类提供的颜色常量指定,也可以通过Color.rgb(int red,int green,int blue)方法指定

 setAlpha(int a)
 用于设置透明度,值为0~255之间的整数

 setAntiAlias(boolean aa)
 用于指定是否使用抗锯齿功能,如果使用会使绘图速度变慢

 setDither(boolean dither)
 用于指定是否使用图像抖动处理,如果使用会使图像颜色更加平滑和饱满,更加清晰

 setShader(Shader shader)
 用于设置渐变,可以使用LinearGradient(线性渐变)、RadialGradient(径向渐变)或
者SweepGradient(角度渐变)

 setStrokeWidth(float width)
 用于设置笔触的宽度

 setStyle(Paint.Style style)
 用于设置填充风格,参数值
为`Style.FILL``Style.FILL_AND_STROKE``Style.STROKE`

 setTextAlign(Paint.Align align)
 用于设置绘制文本时的文字对齐方式,参数值为`Align.CENTER``Align.LEFT``Align.RIGHT`

 setTextSize(float textSize)
 用于设置绘制文本时的文字的大小

线性渐变

  1. new LinearGradient(0, 0, 50, 50, Color.RED, Color.GREEN, Shader.TileMode.MIRROR);
  2. 参数一为渐变起初点坐标x位置
  3. 参数二为y轴位置
  4. 参数三和四分别对应渐变终点
  5. 最后参数为平铺方式,这里设置为镜像

径向渐变

  1. new RadialGradient(160, 110, 50, Color.RED, Color.GREEN, Shader.TileMod
    e.MIRROR);
  2. 参数一,参数二为渐变圆中心坐标
  3. 参数三为半径
  4. 参数四,参数五,参数六与线性渲染相同

角度渐变

  1. new SweepGradient(265, 110, new int[] { Color.RED, Color.GREEN, Color.B
    LUE }, null);
  2. 参数一参数二为渲染中心点x,y坐标
  3. 参数三为围绕中心渲染的颜色数组,至少要有两种颜色值
  4. 参数四为相对位置的颜色数组,若为null,颜色沿渐变线均匀分布

Bitmap类

Bitmap类代表位图,它是Android系统中图像处理的最重要类之一,使用它不仅可以获取图像
文件信息,进行图像剪切,旋转,缩放等操作,而且还可以指定格式保存图像文件。
Bitmap类常用的方法

compress(Bitmap.CompressFormat format, int quality, OutputStream
stream)
 用于将Bitmap对象压缩为指定格式并保存到指定的文件输出流中,其中format参数值可以是Bitmap.CompressFormat.PNG、Bitmap.CompressFormat. JPEG和Bitmap.CompressFormat.WEBP

 createBitmap(Bitmap source, int x, int y, int width, int height, Matrixm, boolean filter)
5. 用于从源位图的指定坐标点开始,“挖取”指定宽度和高度的一块图像来创建新的Bitmap对象,
并按Matrix指定规则进行变换

 createBitmap(int width, int height, Bitmap.Config config)
 用于创建一个指定宽度和高度的新的Bitmap对象

 createBitmap(Bitmap source, int x, int y, int width, int height)
 用于从源位图的指定坐标点开始,“挖取”指定宽度、和高度的一块图像来创建新的Bitmap对象

 createBitmap(int[] colors, int width, int height, Bitmap.Config config)
 使用颜色数组创建一个指定宽度和高度的新Bitimap对象,其中,数组元素的个数为width*height

 createBitmap(Bitmap src)
 用于使用源位图创建一个新的Bitmap对象

 createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)
 用于将源位图缩放为指定宽度和高度的新的Bitmap对象

 isRecycled()
 用于判断Bitmap对象是否被回收

 recycle()
 强制回收Bitmap对象

BitmapFactory类

该类为一个工具类,用于从不同的数据源来解析,创建BitMap对象。
decodeFile(String pathName) 用于从给定的路径所指定的文件中解析、创建Bitmap对象
decodeResource(Resources res, int id) 用于根据给定的资源ID从指定的资源中解析、创建
Bitmap对象
decodeStream(InputStream is) 用于从指定的输入流中解析、创建Bitmap对象

Canvas类

通过该类提供的方法,可以绘制各种图形,如,矩形,圆形,和线条等,通常情况下,要在
Andaroid中绘图,需要先创建一个继承自View类的视图,并且在该类中重写它的
onDraw(Canvas canvas)方法,然后在显示绘图的Activity中添加该视图。

绘制几何图形

Android提供了强大的二维图形库,比较常用的是绘制几何图形,绘制文本,路径和图片等
比较常见的图形包括点,线,弧,圆形,矩形,在Android中,Canvas类提供了丰富的绘制几何图形的
方法,通过这些方法可以绘制出各种几何图形,常用的绘制几何图形的方法如下:
android 中的绘制类Paint 画笔,Canvas 画布,Bitmap 类和BitmapFactory及自定义属性_第1张图片

绘制文本

在Android中,可以通过TextView来显示文本,但是,在开发游戏时,特别是开发RPG类游戏时,会
包含很多文字 ,使用TextView和图片显示文本不太合适,这时,就需要通过绘制文本的方式来实
现,Canvas类提供了一系列的绘制文本的方法

    drawText(String text,float x,float y, Paint paint)
     参数分别是,要绘制的文本,文字的起始位置X坐标,文字起始位置的Y坐标
     drawPosText(String text,float[] pos Paint paint)
    参数分别是,要绘制的文本,每个字符的位置,该方法已过期

文字对齐使用Paint的TextAlign

绘制路径

在Android中,提供了绘制路径的功能,绘制一条路径可以分为创建路径和绘制定义好的路径两
部分
创建路径:
使用 android.graphics.Path 类来实现,Path类包含一组矢量绘图方法,如,画圆,矩形,弧,线条
等,常用的方法如下

addArc(RectF oval, float startAngle, float sweepAngle)
 添加弧形路径

 addCircle(float x, float y, float radius, Path.Direction dir)
 添加圆形路径
 //Path.Direction类型的常量,可选值为Path.Direction.CW(顺时针)和Path.Direction.CCW(逆时针).下面同。

 addOval(RectF oval, Path.Direction dir)
 添加椭圆形路径

 addRect(RectF rect, Path.Direction dir)
 添加矩形路径

 addRoundRect(RectF rect, float rx, float ry, Path.Direction dir)
 添加圆角矩形路径

 moveTo(float x, float y)
 设置开始绘制直线的起始点

 lineTo(float x, float y)
 在moveTo()方法设置的起始点与该方法指定的结束点之间画一条直线,如果在调用该方法之前
没使用moveTo()方法设置起始点,那么将从(0,0)点开始绘制直线

 quadTo(float x1, float y1, float x2, float y2)
 用于根据指定的的参数绘制一条线段轨迹

 close()
 闭合路径

自定义属性

我们在XML布局下经常使用的id,layout_width,layout_height等等参数,那么我们如何定义自
己的属性呢?
我们可以在values中新建一个atts.xml的文件


 <resources>
 <declare-styleable name="MyView">
 <attr name="textColor" format="color" /> //格式列表见下
 <attr name="textSize" format="dimension" />
 declare-styleable>
 resources>

自定义属性格式

1.reference 引用
2. color 颜色
3. boolean 布尔值
4. dimension 尺寸值
5. float 浮点值
6. integer 整型值
7. string 字符串
8.enum 枚举值

在布局文件中使用自定义属性

 xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res/包名"
 android:layout_width="match_parent"
 android:layout_height="match_parent" >

<包名.MyView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 app:textColor="#f00"
app:textSize="20dp" />
 

然后我们在自定义View中实现带AttributeSet属性的构造方法,并且获取自定义值

 public MyView(Context context, AttributeSet attrs) {
 super(context, attrs);
 mPaint = new Paint();
 //将属性数组提取出来
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyView);
 //获取对应的自定义属性,并且给默认值
 int textColor = a.getColor(R.styleable.MyView_textColor, 0X000000);
float textSize = a.getDimension(R.styleable.MyView_textSize, 36);
//将值设置给画笔,绘画后颜色和大小就已经改变成我们自定义属性的值
 mPaint.setTextSize(textSize);
mPaint.setColor(textColor);
 //释放
ta.recycle();15. }

将自定义属性加载需要用到TypedArray类,它位于 android.content.res.TypedArray
包含函数 obtainStyledAttributes(AttributeSet, int[], int, int) 或
者 obtainAttributes(AttributeSet, int[]) 检索的数组值。
在执行完之后,一定要确保调用 recycle() 函数。用于检索从这个结构对应于给定的属性位置
到obtainStyledAttributes中的值。


Bitmap

compress Bitmap.CompressFormat 格式 jpeg png,int quality 压缩,OutputStream os
输出的地方
createBitmap 创建一张空的图片 0000黑色

BitmapFactory类 是Bitmap的加载类

decodeFile (文件名)
decodeStream网络权限
URl url = new URL(“图片地址”);
url.openStream();返回一个流
//1.子线程无法刷新UI
//2.主线程无法请求网络

自定义属性

在values目录下创建一个resource 一般以控件_attrs来命名
 在里面建立declare-styleable name="组件名称"
 在建立 attr属性,format:booleaninteger,float,String,尺寸,color,
引用(drawable),多种以|连接
 在布局中使用,需要导入命名空间
 xmlns:app="http://schemas.android.com/apk/res-auto"
 可以再自定义控件中 添加自定义属性
 解析:在xml的构造方法中去获取TypedArray
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.ArcProgressBar);
 通过 a.getString Integer Int Color Dim.. 获取数值,有些需要默认值
一定需要释放a.recycle();

示例如下:一个跟着鼠标走的小球

android 中的绘制类Paint 画笔,Canvas 画布,Bitmap 类和BitmapFactory及自定义属性_第2张图片

MainActivity 类

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new QiuView(this));
    }
}

QiuView 类

public class QiuView extends View {

    Paint paint = new Paint();


    PointF point = new PointF();

    public QiuView(Context context) {
        super(context);
        paint.setColor(Color.RED);
        paint.setAntiAlias(true);
        paint.setDither(true);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(point.x, point.y, 50, paint);
    }


    //   触摸事件
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            point.set(event.getX(), event.getY());
            invalidate();
        }
        return true;
    }
}

示例二:画一个路径

android 中的绘制类Paint 画笔,Canvas 画布,Bitmap 类和BitmapFactory及自定义属性_第3张图片

MainActivity 类

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new PathView(this));
    }
}

PathView 类

public class PathView extends View {

    Paint paint = new Paint();
    Path path = new Path();
    public PathView(Context context) {
        super(context);
        paint.setAntiAlias(true);
        paint.setDither(true);
        paint.setStyle(Paint.Style.STROKE);
        path.moveTo(200,150);
        path.lineTo(300,400);
        path.quadTo(451,151,260,750);

    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPath(path,paint);
        canvas.drawTextOnPath("跟着PATH路径行走的文字。。。",path,200,0,paint);
    }
}

示例三:如下图,第一个按钮是保存本地,第二个按钮是从本地取一张图片,第三个按钮是从网络读取一张图片

android 中的绘制类Paint 画笔,Canvas 画布,Bitmap 类和BitmapFactory及自定义属性_第4张图片

MainActivity 类

public class MainActivity extends AppCompatActivity {

    Bitmap bmp;
    ImageView iv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bmp = Bitmap.createBitmap(200, 200, Bitmap.Config.RGB_565);
        iv = (ImageView) findViewById(R.id.iv);
        //200*200 = 40000 = 40b 1024
        iv.setImageBitmap(bmp);
    }

    public void save(View v) {
        //jpg没有透明度
        String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/aaa.png";
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(path);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
        try {
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void fromFile(View v) {
        //需要读取权限
        String fileName = Environment.getExternalStorageDirectory().getAbsolutePath() + "/fbb.jpg";
        Bitmap bmp = BitmapFactory.decodeFile(fileName);
        iv.setImageBitmap(bmp);

    }

    //使用Image框架
    public void fromStream(View v) {
        //从网络
        //域名
        new Thread() {
            @Override
            public void run() {
                URL url = null;
                try {
                    url = new URL("https://img.alicdn.com/tps/TB1l033MVXXXXbrXVXXXXXXXXXX-520-280.jpg");
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }
                try {
                    //1.子线程无法刷新UI
                    //2.主线程无法请求网络
                    InputStream is = url.openStream();
                    final Bitmap bmp = BitmapFactory.decodeStream(is);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            iv.setImageBitmap(bmp);
                        }
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();


    }
}


xml


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.administrator.lesson12_bitmap.MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="save" />

    <Button
        android:onClick="fromFile"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:text="从本地加载图片"/>

    <Button
        android:onClick="fromStream"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="200dp"
        android:text="从网路加载图片"/>

    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />
RelativeLayout>

权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />

你可能感兴趣的:(Android)