Android Paint应用一

本文详细介绍了Android中的Paint类,包括其构造方法、 StrokeCap属性的设置,以及各种渲染器如LinearGradient、BitmapShader的使用。通过实例展示了如何改变线条末端形状,创建颜色渐变和位图渲染效果,并探讨了TileMode的不同模式对渲染的影响。同时,提到了FontMetrics对象在字体度量中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Paint 顾名思义就是画笔,可以用来设置颜色、测量文字、设置图层混合模式、颜色滤镜等等。
Api中提供了两个构造方法Paint()和Paint(int flags),其中flags的值有以下几种:

  /**
     * int flags
     * //抗锯齿标志
     * public static final int ANTI_ALIAS_FLAG     = 0x01;
     * //使位图过滤的位掩码标志 图像在动画进行中会滤掉对Bitmap图像的优化操作,加快显示
     * //速度,本设置项依赖于dither和xfermode的设置
     * public static final int FILTER_BITMAP_FLAG  = 0x02;
     * //使位图进行有利的抖动的位掩码标志 会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
     * public static final int DITHER_FLAG         = 0x04;
     * //下划线
     * public static final int UNDERLINE_TEXT_FLAG = 0x08;
     * //中划线
     * public static final int STRIKE_THRU_TEXT_FLAG = 0x10;
     * //加粗
     * public static final int FAKE_BOLD_TEXT_FLAG = 0x20;
     * //使文本平滑线性扩展的标志
     * public static final int LINEAR_TEXT_FLAG    = 0x40;
     * //使文本的亚像素定位的绘图标志
     * public static final int SUBPIXEL_TEXT_FLAG  = 0x80;
     * //绘制文本时允许使用位图字体的绘图标志
     * public static final int EMBEDDED_BITMAP_TEXT_FLAG = 0x400;
     */

以ANTI_ALIAS_FLAG为例,调用第二个构造方法和调用paint.setAntiAlias(boolean flag);的效果是一样的。
下面看一下paint提供的其他方法

    mPaint = new Paint();
    //设置画笔颜色
    mPaint.setColor(Color.RED);
     //设置字体大小
    mPaint.setTextSize(20);
    //设置描边效果  FILL填充 STROKE描边  FILL_AND_STROKE填充+描边
    mPaint.setStyle(Paint.Style.STROKE); 
    //设置描边宽度
    mPaint.setStrokeWidth(15);
    //设置图层混合模式,18种
    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    //设置字体风格,加粗、倾斜等
    mPaint.setTypeface(Typeface.SANS_SERIF);
    //设置下划线
    mPaint.setUnderlineText(true);
    //设置删除线,即setFlags(STRIKE_THRU_TEXT_FLAG)
    mPaint.setStrikeThruText(true);
    //设置倾斜弧度
    mPaint.setTextSkewX(2);
    //设置文字X方向缩放值
    mPaint.setTextScaleX(0.7f);
    //设置文字对齐方式
    mPaint.setTextAlign(Paint.Align.CENTER);
    //设置画笔图形样式,如圆形ROUND或者方形SQUARE
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    //设置图像抖动处理
    mPaint.setDither(true);
    //设置颜色过滤器
    mPaint.setColorFilter(new ColorMatrixColorFilter((float[]) null));
    //设置抗锯齿
    mPaint.setAntiAlias(true);
    //设置透明度,取值范围[0..255]
    mPaint.setAlpha(0);
    //设置颜色值及透明度,参数取值范围[0..255]
    mPaint.setARGB(0,0,0,0);
    //模拟实现粗体文字
    mPaint.setFakeBoldText(true);
    //在动画进行中会滤掉对Bitmap图像的优化操作,加快显示速度,本设置项依赖于dither和xfermode的设置
    mPaint.setFilterBitmap(true);
    //设置画笔遮罩滤镜 
    mPaint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.SOLID));
    //设置渲染器 线性渲染LinearGradient,环形渲染SweepGradient ,扫描渲染RadialGradient,位图渲染BitmapShader
    mPaint.setShader(new LinearGradient(0,0,250,250,new int[]{Color.BLUE,Color.GREEN},new float[]{0.6f,1f}, Shader.TileMode.CLAMP));
    //设置图形的结合方式
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    //测量文本大小,并存储在Rect对象中
    mPaint.getTextBounds(str,0,str.length(),new Rect());
    //获取文本的宽
    mPaint.measureText(str);
    //获取字体度量对象
    mPaint.getFontMetrics();

mPaint.setStrokeCap(Paint.Cap.ROUND),该方法传递的参数包括ROUND圆角类型,SQUARE方形,BUTT默认类型,表示在末端添加一小段圆角或者方形,以画线为例。

        mPaint.setStrokeCap(Paint.Cap.BUTT);
        canvas.drawLine(100,100,600,100,mPaint);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        canvas.drawLine(100,300,600,300,mPaint);
        mPaint.setStrokeCap(Paint.Cap.SQUARE);
        canvas.drawLine(100,500,600,500,mPaint);

这里画了3条直线,并分别设置了相应的StrokeCap值,看一下效果
在这里插入图片描述
第一条直线是默认类型也就是BUTT类型,第二条是ROUND类型,第三条是SQUARE类型,我们发现,第二条直线末端添加了一小段圆角,第三条直线添加了一小段方形。

下面看一下渲染器 mPaint.setShader(Shader shader)方法,系统主要提供了四种渲染方式:线性渲染LinearGradient,环形渲染SweepGradient ,扫描渲染RadialGradient,位图渲染BitmapShader,除此以外还有一种组合渲染ComposeShader。

以LinearGradient为例,LinearGradient的构造方法 LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int colors[], @Nullable float positions[], @NonNull TileMode tile)
参数说明:x0,y0表示渲染起始坐标。x1,y1表示渲染终点坐标。colors[]表示渲染颜色数组,positions[]表示渲染颜色所占比(positions[]的长度与colors[]必须保持一致)。TileMode 渲染模式(CLAMP,REPEAT,MIRROR)

         mPaint.setShader(new LinearGradient(0,0,250,250,new int[]{Color.BLUE,Color.GREEN},new float[]{0.6f,1f}, Shader.TileMode.CLAMP));
        canvas.drawRect(50, 50, 250, 250, mPaint);
        mPaint.setShader(new LinearGradient(0,0,500,500,new int[]{Color.BLUE,Color.GREEN},null, Shader.TileMode.CLAMP));
        canvas.drawRect(50, 300, 250, 500, mPaint);

在这里插入图片描述
在第一张图中,明显蓝色与绿色的占比不同,在代码中我们设置了new float[]{0.6f,1f}这样的参数,它表示Color.BLUE颜色占比至60%,60%至100%(开区间) 是Color.BLUE,Color.GREEN两者的渐变,100% 是Color.GREEN。
第二张图则没有设置该参数,是默认渲染效果。

在位图渲染中,也就是BitmapShader,构造方法

 public BitmapShader(@NonNull Bitmap bitmap, @NonNull TileMode tileX, @NonNull TileMode tileY) {
        this(bitmap, tileX.nativeInt, tileY.nativeInt);
    }

bitmap表示即将渲染的位图,tileX 表示X方向的渲染模式,tileY 表示Y方向的渲染模式,TileMode包含三种模式CLAMP,REPEAT,MIRROR。

TileMode.CLAMP模式 表示如果绘制部分超出渲染区域,那么会拉伸最后一个像素来填充超出部分

        canvas.drawBitmap(resultBitmap,0,400,mPaint);
        Shader mShader = new BitmapShader(resultBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        mPaint.setShader(mShader);
        canvas.drawRect(0, 0, 300, 300, mPaint);

效果如下图
在这里插入图片描述
TileMode.REPEAT模式 如果绘制部分超出渲染区域,那么会重复排版直至填充完超出部分
TileMode.MIRRO模式 如果绘制部分超出渲染区域,X方向上下翻转,Y方向左右翻转直至填充完超出部分
这里我们将设置X方向为REPEAT,Y方向为MIRRO

  		Shader mShader = new BitmapShader(resultBitmap, Shader.TileMode.REPEAT, Shader.TileMode.MIRROR);
        mPaint.setShader(mShader);
        canvas.drawRect(0, 0, 300, 300, mPaint);

在这里插入图片描述
可以很明显的观察到水平方向是重复绘制,垂直方向是镜像绘制。

再看一下ComposeShader 组合渲染,构造方法

   public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB,
            @NonNull PorterDuff.Mode mode) {
        this(shaderA, shaderB, mode.nativeInt);
    }
       public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull Xfermode mode) {
        this(shaderA, shaderB, mode.porterDuffMode);
    }

参数说明
shaderA,shaderB:要混合的两种shader
Xfermode mode: 组合两种shader颜色的模式
PorterDuff.Mode mode: 组合两种shader颜色的模式

 BitmapShader bitmapShader = new BitmapShader(resultBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
        LinearGradient linearGradient = new LinearGradient(0, 0, 1000, 1600, new int[]{Color.RED, Color.GREEN, Color.BLUE}, null, Shader.TileMode.CLAMP);
        Shader mShader = new ComposeShader(bitmapShader, linearGradient, PorterDuff.Mode.MULTIPLY);
        mPaint.setShader(mShader);
        canvas.drawCircle(250, 250, 250, mPaint);

这里采用了位图渲染+线性渲染的组合渲染模式,看一下效果
在这里插入图片描述
最后再来看一下 mPaint.getFontMetrics(); 字体度量对象FontMetrics,api中提供了以下几个变量

 /**
         * The maximum distance above the baseline for the tallest glyph in
         * the font at a given text size.
         */
        public float   top;
        /**
         * The recommended distance above the baseline for singled spaced text.
         */
        public float   ascent;
        /**
         * The recommended distance below the baseline for singled spaced text.
         */
        public float   descent;
        /**
         * The maximum distance below the baseline for the lowest glyph in
         * the font at a given text size.
         */
        public float   bottom;
        /**
         * The recommended additional space to add between lines of text.
         */
        public float   leading;

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值