Adroid Paint属性(图形、文字)

Paint mPaint = new Paint();//初始化画笔
mPaint.setColor(Color.BLUE);//设置画笔颜色
mPaint.setAlpha(255);//设置透明度 0-255
mPaint.setStrokeWidth(3);//设置画笔宽度
canvas.drawLine(100,100,300,100,mPaint);//画线
// mPaint.setStyle ()
// Paint.Style.FILL 只绘制图形内容
// Paint.Style.STROKE 只绘制图形轮廓(描边)
// Paint.Style.FILL_AND_STROKE 既绘制轮廓也绘制内容
mPaint.reset();//重置
String DRAW_TEXT = "涂文远";
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(3);
mPaint.setTextSize(100);
mPaint.setAntiAlias(true);//获取与设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢,一般会开启。设置后会平滑一些;
mPaint.setDither(true);//获取与设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满、图像更加清晰。
//测量文本高
Rect textBounds = new Rect();
mPaint.getTextBounds(DRAW_TEXT, 0, DRAW_TEXT.length(), textBounds);
int textH = textBounds.height();
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawText(DRAW_TEXT,0,100+textH*0,mPaint);

mPaint.setStyle(Paint.Style.FILL);
canvas.drawText(DRAW_TEXT,0,100+textH*1,mPaint);

mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawText(DRAW_TEXT,0,100+textH*2,mPaint);

//mPaint.setStrokeCap
//Paint.Cap.BUTT(无线冒)
//Paint.Cap.ROUND(圆形线冒)
//Paint.Cap.SQUARE(方形线冒)
mPaint.reset();
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(50);

mPaint.setStrokeCap(Paint.Cap.BUTT);
canvas.drawLine(100,100,300,100,mPaint);

mPaint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawLine(100,200,300,200,mPaint);

mPaint.setStrokeCap(Paint.Cap.SQUARE);
canvas.drawLine(100,300,300,300,mPaint);

//mPaint.setStrokeJoin();
//Paint.Join.BEVEL 结合处为直线
//Paint.Join.ROUND 结合处为圆弧
//Paint.Join.MITER 结合处为锐角
mPaint.reset();
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(50);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setAntiAlias(true);
Path path = new Path();
path.moveTo(100,100);
path.lineTo(300,100);
path.lineTo(100,300);
path.close();
mPaint.setStrokeJoin(Paint.Join.BEVEL);
canvas.drawPath(path,mPaint);

Path path1 = new Path();
path1.moveTo(100,400);
path1.lineTo(300,400);
path1.lineTo(100,600);
path1.close();
mPaint.setStrokeJoin(Paint.Join.ROUND);
canvas.drawPath(path1,mPaint);

Path path2 = new Path();
path2.moveTo(100,700);
path2.lineTo(300,700);
path2.lineTo(100,900);
path2.close();
mPaint.setStrokeJoin(Paint.Join.MITER);
canvas.drawPath(path2,mPaint);

Paint之setXfermode--图形混合模式

setXfermode(Xfermode xfermode)

  • 在继承Xfermode这个类有三个子类AvoidXfermode,PixelXorXfermode,PorterDuffXfermode
  • AvoidXfermode,PixelXorXfermode是完全不支持硬件加速的,而PorterDuffXfermode是部分不支持的
public class TestPaintView extends View {

    private final Bitmap srcBmp;//源图像
    private final Bitmap dstBmp;//目标图像
    private final Paint mPaint;

    public TestPaintView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
        srcBmp = makeSrc(400, 400);
        dstBmp = makeDst(400, 400);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int layerID = canvas.saveLayer(0,0,800,800,mPaint,Canvas.ALL_SAVE_FLAG);
        canvas.drawBitmap(dstBmp, 0, 0, mPaint);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        canvas.drawBitmap(srcBmp,200,200, mPaint);
        mPaint.setXfermode(null);
        canvas.restoreToCount(layerID);
    }

    // create a bitmap with a circle, used for the "dst" image
    static Bitmap makeDst(int w, int h) {
        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bm);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        p.setColor(0xFFFFCC44);
        c.drawOval(new RectF(0, 0, w, h), p);
        return bm;
    }
    // create a bitmap with a rect, used for the "src" image
    static Bitmap makeSrc(int w, int h) {
        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bm);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        p.setColor(0xFF66AAFF);
        c.drawRect(0, 0, w, h, p);
        return bm;
    }

}

 

PorterDuff.Mode

public class TestPaintView extends View {
    private final Bitmap srcBmp;//源图像
    private final Bitmap dstBmp;//目标图像
    private final Paint mPaint;
    private PorterDuff.Mode mode = PorterDuff.Mode.SCREEN;
    private final Paint paint2;

    public TestPaintView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
        srcBmp = makeSrc(400, 400);
        dstBmp = makeDst(400, 400);
        paint2 = new Paint();
        paint2.setColor(Color.YELLOW);
        paint2.setStyle(Paint.Style.STROKE);
        paint2.setDither(true);
        paint2.setStrokeWidth(1);
        paint2.setTextSize(100);
        paint2.setAntiAlias(true);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int layerID = canvas.saveLayer(0,0,800,800,mPaint,Canvas.ALL_SAVE_FLAG);
        paint2.setColor(Color.GREEN);
        paint2.setStyle(Paint.Style.STROKE);
        canvas.drawRect(100-1f,0f,501f,402f,paint2);
        canvas.drawBitmap(dstBmp, 100, 1, null);
        mPaint.setXfermode(new PorterDuffXfermode(mode));
        canvas.drawBitmap(srcBmp,100,1, mPaint);
        mPaint.setXfermode(null);
        canvas.restoreToCount(layerID);
        paint2.setColor(Color.RED);
        paint2.setStyle(Paint.Style.FILL);
        canvas.drawText(mode.name(),50,350,paint2);

    }
    static Bitmap makeDst(int w, int h) {
        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bm);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        p.setColor(0xFFE81E63);
        c.drawOval(new RectF(w/4, h/4, w/4+w/2, h/4+h/2), p);
        return bm;
    }
    // create a bitmap with a rect, used for the "src" image
    static Bitmap makeSrc(int w, int h) {
        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bm);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        p.setColor(0xFF2195F2);
        c.drawRect(0, h/2, w/2, h, p);
        return bm;
    }

    public void setPorterDuffXfermode(PorterDuff.Mode mode){
        this.mode = mode;
        postInvalidate();
    }
}

//setMaskFilter(MaskFilter maskfilter);
//设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等
//MaskFilter的两个子类BlurMaskFilter和EmbossMaskFilter
mPaint.setColor(Color.RED);
setLayerType(LAYER_TYPE_SOFTWARE,null);//关闭硬件加速
//第一个参数:radius很容易理解,值越大我们的阴影越扩散,用过PS的人会很容易理解,其实就是阴影范围。
//第二个参数:style表示的是模糊的类型 SOLID,NORMAL,OUTER和INNER
mPaint.setMaskFilter(new BlurMaskFilter(20,BlurMaskFilter.Blur.SOLID));//这个方法已经被标注为过时的方法了,如果你的应用启用了硬件加速,你是看不到任何阴影效果的。
canvas.drawRect(200,200,600,600,mPaint);

setColorFilter(ColorFilter colorfilter);   
设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果

setShader(Shader shader);   
设置图像效果,使用Shader可以绘制出各种渐变效果 

Shader 子类 BitmapShader,ComposeShader,LinearGradient,RadialGradient,SweepGradient

BitmapShader

BitmapShader (Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)

  • 第一个参数:要处理的bitmap对象
  • 第二个参数:在X轴处理的效果,Shader.TileMode里有三种模式:CLAMP、MIRROR和REPETA
  • 第三个参数:在Y轴处理的效果,Shader.TileMode里有三种模式:CLAMP、MIRROR和REPETA
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.mv);
// 设置shader
mPaint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
// 用设置好的画笔绘制一个矩形
canvas.drawRect(0, 0, 800, 800, mPaint);

Shader.TileMode.CLAMP 会将边沿一个像素进行拉伸、扩展。

Shader.TileMode.MIRROR 镜像

Shader.TileMode.REPEAT 重复模式

mPaint.setAntiAlias(true);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.mv);
// 设置shader
mPaint.setShader(new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));
canvas.drawCircle(400, 400, 300, mPaint);

LinearGradient

它就是一个线性渐变的处理类,有两个构造方法

public LinearGradient (float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)

(x0,y0)表示渐变的起点座标而(x1,y1)则表示渐变的终点座标 而color0和color1则表示起点的颜色和终点的颜色。TileMode和上面讲的完全一致

public LinearGradient (float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile)

座标都是一样的,但这里的colors和positions都是数组,也就是说我们可以传入多个颜色和颜色的位置,产生更加丰富的渐变效果

测试第一个构造方法

Shader shader = new LinearGradient(0, 0, 200, 200, Color.RED, Color.YELLOW, Shader.TileMode.REPEAT);
// 设置shader
mPaint.setShader(shader);  
canvas.drawRect(0, 0, 600, 600, mPaint);

测试第二个构造方法

Shader shader = new LinearGradient(0, 0, 200, 200,
                new int[] { Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN, Color.BLUE },
                new float[] { 0, 0.1F, 0.5F, 0.7F, 0.8F }, Shader.TileMode.REPEAT);
mPaint.setShader(shader);
canvas.drawRect(0, 0, 600, 600, mPaint);

SweepGradient

它的意思是梯度渐变,也称之为扫描式渐变,因为其效果有点类似雷达的扫描效果,他也有两个构造方法

第一个

SweepGradient(float cx, float cy, int color0, int color1)  

参数(cx,cy)是远行的座标,产生从color0到color1的渐变

mPaint.setAntiAlias(true);
Shader shader = new SweepGradient(300,300,Color.GREEN,Color.RED);
mPaint.setShader(shader);
canvas.drawCircle(300, 300, 300, mPaint);

第二个

SweepGradient(float cx, float cy, int[] colors, float[] positions)  

mPaint.setAntiAlias(true);
Shader shader = new SweepGradient(300,300,new int[]{Color.GREEN,Color.RED,Color.YELLOW},new float[]{0.1f,0.5f,0.8f});
mPaint.setShader(shader);
canvas.drawCircle(300, 300, 300, mPaint);

RadialGradient

径向渐变,径向渐变说的简单点就是个圆形中心向四周渐变的效果,他也一样有两个构造方法

第一个

RadialGradient (float centerX, float centerY, float radius, int centerColor, int edgeColor, Shader.TileMode tileMode) 

(centerX,centerY)是圆心的座标,radius是半径,centerColor是边缘的颜色,edgeColor是外围的颜色,最后是模式

mPaint.setAntiAlias(true);
Shader shader = new RadialGradient(300,300,200,Color.RED,Color.GREEN,Shader.TileMode.REPEAT);
mPaint.setShader(shader);
canvas.drawCircle(300, 300, 300, mPaint);

第二个

RadialGradient (float centerX, float centerY, float radius, int[] colors, float[] stops, Shader.TileMode tileMode) 

这个就是添加了多个色彩,设置色彩的位置

mPaint.setAntiAlias(true);
Shader shader = new RadialGradient(300,300,200,new int[]{Color.RED,Color.GREEN,Color.YELLOW},new float[]{0.2f,0.5f,0.8f},Shader.TileMode.REPEAT);
mPaint.setShader(shader);
canvas.drawCircle(300, 300, 300, mPaint);

ComposeShader

就是组合Shader的意思,顾名思义就是两个Shader组合在一起作为一个新Shader,它有两个构造方法:

ComposeShader (Shader shaderA, Shader shaderB, Xfermode mode)  

ComposeShader (Shader shaderA, Shader shaderB, PorterDuff.Mode mode)  

两个都差不多的,只不过一个指定了只能用PorterDuff的混合模式而另一个只要是Xfermode下的混合模式都没问题

mPaint.setAntiAlias(true);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.mv);
Shader shader01 = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
Shader shader02 = new LinearGradient(0, 0, 0, 100, new int[] {
Color.WHITE, Color.LTGRAY, Color.TRANSPARENT, Color.GREEN }, null,Shader.TileMode.MIRROR);
// 设置shader
mPaint.setShader(new ComposeShader(shader01, shader02, PorterDuff.Mode.MULTIPLY));
canvas.drawCircle(300, 300, 300, mPaint);

setShadowLayer(float radius ,float dx,float dy,int color)

在图形下面设置阴影层,产生阴影效果,radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色  

mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setTextSize(50);
mPaint.setColor(Color.BLACK);
mPaint.setShadowLayer(5,3,3,Color.RED);
canvas.drawText("涂文远",0,100,mPaint);

负责获取文字相关

float getFontSpacing() 
                获取字符行间距。
                float getLetterSpacing() 
                void setLetterSpacing(float letterSpacing) 
                设置和获取字符间距
                
                final boolean isUnderlineText() 
                void setUnderlineText(boolean underlineText) 
                是否有下划线和设置下划线。
                final boolean isStrikeThruText() 
                void setStrikeThruText(boolean strikeThruText) 
                获取与设置是否有文本删除线。
                
                float getTextSize() 
                void setTextSize(float textSize) 
                获取与设置文字大小,注意:Paint.setTextSize传入的单位是px,TextView.setTextSize传入的单位是sp,注意使用时不同分辨率处理问题。
                
                Typeface getTypeface() 
                Typeface setTypeface(Typeface typeface) 
                获取与设置字体类型。Android默认有四种字体样式:BOLD(加粗)、BOLD_ITALIC(加粗并倾斜)、ITALIC(倾斜)、NORMAL(正常),我们也可以通过Typeface类来自定义个性化字体。
                
                float getTextSkewX() 
                void setTextSkewX(float skewX) 
                获取与设置文字倾斜,参数没有具体范围,官方推荐值为-0.25,值为负则右倾,为正则左倾,默认值为0。
                
                Paint.Align getTextAlign() 
                void setTextAlign(Paint.Align align) 
                获取与设置文本对齐方式,取值为CENTER、LEFT、RIGHT,也就是文字绘制是左边对齐、右边还是局中的。

                setSubpixelText(boolean subpixelText)
                固定的几个范围:320*480,480*800,720*1280,1080*1920等等;那么如何在同样的分辨率的显示器中增强显示清晰度呢?
                亚像素的概念就油然而生了,亚像素就是把两个相邻的两个像素之间的距离再细分,再插入一些像素,这些通过程序加入的像素就是亚像素。在两个像素间插入的像素个数是通过程序计算出来的,一般是插入两个、三个或四个。
                所以打开亚像素显示,是可以在增强文本显示清晰度的,但由于插入亚像素是通过程序计算而来的,所以会耗费一定的计算机性能。
                
                int breakText(String text, boolean measureForwards, float maxWidth, float[] measuredWidth) 
                比如文本阅读器的翻页效果,我们需要在翻页的时候动态折断或生成一行字符串,这就派上用场了~

                
                
                计算指定参数长度能显示多少个字符,同时可以获取指定参数下可显示字符的真实长度,譬如:
                
                private static final String STR = "动脑ABCDEF";
                mPaint.setTextSize(50);
                float[] value = new float[1];
                int ret = mPaint.breakText(STR, true, 200, value);
                Log.i("YYYY", "breakText="+ret+", STR="+STR.length()+", value="+value[1]);
                //breakText=5, STR=8, value=195.0

                void getTextBounds(char[] text, int index, int count, Rect bounds) 
                void getTextBounds(String text, int start, int end, Rect bounds) 
                获取文本的宽高,通过bounds的Rect拿到整型。

                float measureText(String text) 
                float measureText(CharSequence text, int start, int end) 
                float measureText(String text, int start, int end) 
                float measureText(char[] text, int index, int count) 
                粗略获取文本的宽度,和上面的getTextBounds比较类似,返回浮点数。

                int getTextWidths(String text, int start, int end, float[] widths) 
                int getTextWidths(String text, float[] widths) 
                int getTextWidths(CharSequence text, int start, int end, float[] widths) 
                int getTextWidths(char[] text, int index, int count, float[] widths) 
                精确计算文字宽度,与上面两个类似。

Android 文字基线(BaseLine)算法

String text = "涂文远TWYtwy abcd";
int centery = 300;
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setTextSize(100);
mPaint.setColor(Color.RED);

paint2.reset();
paint2.setColor(Color.GREEN);
paint2.setAntiAlias(true);
canvas.drawLine(0,centery,1000,centery,paint2);//中心线

Paint.FontMetricsInt fontMetricsInt = mPaint.getFontMetricsInt();
int baseliney = centery+(fontMetricsInt.bottom-fontMetricsInt.top)/2-fontMetricsInt.bottom;
canvas.drawLine(0,baseliney,1000,baseliney,paint2);//基线
canvas.drawText(text,0,baseliney,mPaint);

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章