Android中Paint画图(线、虚线、矩形、多边形、圆形、曲线、半圆、三角形、旋转文字)

线

圆角线参考网址:Android自定义View(二) 画圆角线_perfectnihil的博客-CSDN博客_android paint 圆角

private void drawLine(Canvas canvas,
                          float startX,float startY,float stopX,float stopY,
                          float width,int color){
    Paint paint = new Paint();
    paint.setAntiAlias(true);//抗锯齿
    paint.setStyle(Paint.Style.STROKE);//不加这个不显示
    paint.setColor(color);
    paint.setStrokeWidth(width);
    Path mPath = new Path();
    mPath.moveTo(startX, startY);
    mPath.lineTo(stopX, stopY);
    mPath.close();



    //***************旋转线
    //1.
    canvas.save();
    canvas.translate(startX, startY);//根据指定坐标旋转
    //水平翻转
    canvas.scale(-1,1);
    //垂直翻转
    canvas.scale(1,-1);
    canvas.translate(-startX, -startY);
    //2.
    canvas.rotate(90, startX, startY);//根据指定角度、坐标来旋转

    canvas.drawPath(mPath, paint);

    canvas.restore();
    //圆角线(线的两头是圆角),前提是线的起始点坐标不能是画布的边框坐标(不能是0,0和宽、高边)
    paint .setStrokeCap(Paint.Cap.ROUND);
    //设置线条渐变色(颜色可以设置多个)
    int[] colors = new int[2];
    colors[0]= Color.argb(255, 255, 255, 255);
    colors[1]= Color.argb(255, 0, 255, 0);
    LinearGradient shader = new LinearGradient(startX,             
    startY,endX,e,colors,null,Shader.TileMode.CLAMP);
    //Shader.TileMode里有三种模式:CLAMP(拉伸)、MIRROR(镜像)、REPEAT(重复)
}

虚线

参考网址:Android 画虚线 DashPathEffect 使用详解_Android研发曹新雨的博客-CSDN博客

 canvas:动态虚线圆 | 码农家园

 说明:

mPath.close();通过测试发现,此方法是用来形成一个闭合图;例如:只画一条虚线并带有流动效果,如果调用此方法则呈现的效果相当于是两条虚线对向流动,把此方法去掉则可以直观看到流动效果。

private void drawXuXian(Canvas canvas,float startX,float startY,float stopX,float stopY){
    xuXianPaint.setStyle(Paint.Style.STROKE);//不加这个不显示
    xuXianPaint.setColor(context.getResources().getColor(R.color.orange_light));
    xuXianPaint.setStrokeWidth(2);
	//意思是所画虚线规则是先画5个长度的实线,留下10个长度的空白
    //数组规则(必须是偶数个数):实、虚、实、虚---先虚再实,每个数代表长度
    //offSet:代表偏移量(>=0第一个先加实线长度,<0第一个先加虚线长度);配合定时器使用可实现跑马灯效果
    PathEffect effects = new DashPathEffect(new float[]{5, 10}, offSet);
    xuXianPaint.setPathEffect(effects);
    Path mPath = new Path();
    mPath.moveTo(startX, startY);
    mPath.lineTo(stopX, stopY);
    mPath.close();//如果画的不是闭合图形需要把这句去掉
    canvas.drawPath(mPath, xuXianPaint);
}
//虚线实现跑马灯效果
int offSet = 0;
private Handler handler = new Handler(){
	@Override
	public void handleMessage(@NonNull Message msg) {
		super.handleMessage(msg);
		if(offSet > 15){//15表示new float[]{5,10}这个数组中总和
			offSet = 0;
		}
		offSet++;
		invalidate();
	}
};
Runnable task = new Runnable() {
	@Override
	public void run() {
		handler.sendEmptyMessage(0);
		handler.postDelayed(task,10);
	}
};

矩形

private void drawRectangle(Canvas canvas,boolean choose,
                               float left,float top,float right,float bottom,int color){
    Paint paint = new Paint();
    paint.setAntiAlias(true);//抗锯齿
    paint.setColor(color);
    if (choose){
        //设置实心矩形
        paint.setStyle(Paint.Style.FILL);
    }else{
       //设置空心矩形
       paint.setStyle(Paint.Style.STROKE);
    }
    //使用画笔在画布上画矩形
    canvas.drawRect(left,top,right,bottom,paint);
}

多边形

private void drawJuXing(Canvas canvas,int color,float startX,float startY,float startX1,float startY1,
	float startX2,float startY2,float startX3,float startY3){
    juxingPaint.setStyle(Paint.Style.STROKE);//不加这个不显示
    juxingPaint.setColor(color);
    juxingPaint.setStrokeWidth(2);
    juxingPaint.setStyle(Paint.Style.FILL);//是否填充
    Path mPath = new Path();
	float sX = startX*scale+pianyix_huitu;
    float sY = startY*scale+pianyiy_huitu;
	float sX1 = startX1*scale+pianyix_huitu;
    float sY1 = startY1*scale+pianyiy_huitu;
	float sX2 = startX2*scale+pianyix_huitu;
    float sY2 = startY2*scale+pianyiy_huitu;
	float sX3 = startX3*scale+pianyix_huitu;
    float sY3 = startY3*scale+pianyiy_huitu;
	mPath.moveTo(sX, sY);
	mPath.lineTo(sX1, sY1);
	mPath.lineTo(sX2, sY2);
	mPath.lineTo(sX3, sY3);
    mPath.close();
    canvas.drawPath(mPath, juxingPaint);
}

圆形

private void drawYuan(Canvas canvas,boolean choose,
                          float startX,float startY,float radius,int color){
    Paint paint = new Paint();
    paint.setAntiAlias(true);//抗锯齿
    paint.setColor(color);
    if (choose){
       //设置实心圆
       paint.setStyle(Paint.Style.FILL);
    }else{
       //设置空心圆
       paint.setStyle(Paint.Style.STROKE);
    }
    //X、Y坐标,radius半径
   canvas.drawCircle(startX, startY, radius, paint);
}

曲线

 private void drawQuXian(Canvas canvas,boolean choose,float startX,float startY,
							float afterX,float afterY,
                            float stopX,float stopY,
                            float width,int color){
    quxianPaint.setStrokeWidth(width);
    quxianPaint.setColor(color);
    if (choose){
        //设置实心曲线
        quxianPaint.setStyle(Paint.Style.FILL);
    }else{
        //设置空心曲线
        quxianPaint.setStyle(Paint.Style.STROKE);
    }
    Path mPath = new Path();
    mPath.moveTo(startX, startY);//开始点
    mPath.quadTo(afterX, afterY, stopX, stopY);
    canvas.drawPath(mPath, quxianPaint);
}

半圆

private void drawBanYuan(Canvas canvas,float left, float top, float right, float bottom,
                             float width,int color){
    //参考网址:https://blog.csdn.net/fanleiym/article/details/84255231
    banyuanPaint.setStrokeWidth(width);
    banyuanPaint.setStyle(Paint.Style.FILL);
    banyuanPaint.setColor(color);
	if (userCenter){
        banyuanPaint.setStyle(Paint.Style.FILL);//实心
    }else{
        banyuanPaint.setStyle(Paint.Style.STROKE);
    }
    RectF oval = new RectF(left,top,right,bottom);
    //定义的圆弧的形状和大小的范围
    //设置圆弧是从哪个角度来顺时针绘画的
    //设置圆弧扫过的角度
    //true:设置我们的圆弧在绘画的时候,是否经过圆形;设置空心(STROKE)时,参数true没效果
    canvas.drawArc(oval,270,180,userCenter,banyuanPaint);
}

三角形

private void drawTriangle(Canvas canvas,boolean choose,
                              float startX,float startY,
                              float afterX,float afterY,
                              float stopX,float stopY,
                              float width,int color){
    Paint paint = new Paint();
    paint.setAntiAlias(true);//抗锯齿
    paint.setStrokeWidth(width);
    paint.setColor(color);
    if (choose){
       //设置实心三角形
       paint.setStyle(Paint.Style.FILL);
    }else{
       //设置空心三角形
       paint.setStyle(Paint.Style.STROKE);
    }
    Path mPath = new Path();
    mPath.moveTo(startX, startY);
    mPath.lineTo(afterX, afterY);
    mPath.lineTo(stopX, stopY);
    //将mpath封闭,也可以写 mpath.lineTo(100, 100);代替
    mPath.close();
    //绘制path路径
    canvas.drawPath(mPath, paint);
}

旋转文字

private void drawText(Canvas canvas,String str,int size,float degrees,float startX,float             
                     startY,int color){
    Paint paint = new Paint();
    paint.setAntiAlias(true);//抗锯齿        
    paint.setColor(color);
    paint.setTypeface(Typeface.DEFAULT_BOLD);//字体
    Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL);//字体风格
    paint.setTypeface(font);
    paint.setTextSize(size);
    //Paint设置水平居中
    paint.setTextAlign(Paint.Align.CENTER);
    float length = paint.measureText(str);//获取字体的长度
    //获取文字的高度
    //参考网址:http://www.voidcn.com/article/p-zqzznoyl-ce.html
    //1.获取文字高度
    Paint.FontMetrics fm = paint.getFontMetrics();
    float fFontHeight = (float)Math.ceil(fm.descent - fm.ascent);
    //2.获取文字高度---1和2获取到的高度不同
    //参考网址:https://blog.csdn.net/u010661782/article/details/52805939
    //Rect rect = new Rect();
    //textPaint.getTextBounds(str,0,str.length(), rect);
    //fFontHeight = rect.height();
    float ncenterx = startX + (size - length) / 2;
    if (degrees!=0){
       //以指定坐标点旋转指定角度
       canvas.rotate(degrees, ncenterx, startY);
     }
     canvas.drawText(str, ncenterx,startY,paint);
}
//***设置文字居中显示***
private void setTextLocation(){
    String text = “123”;
    textPain.setTextSize(textSize);
    Rect rect = new Rect();
    textPain.getTextBounds(text, 0, text.length(), rect);
    height+rect.height();//获取字体高度
    float length = textPain.measureText(text);//获取字体长度
    //x坐标是文字第一个字的位置,y坐标是文字顶部的位置,所以上下居中需要+字体高度
    canvas.drawText(text, (width-length)/2, (height+rect.height())/2, textPain);
}

Canvas转Bitmap,可把bitmap转png图片保存到手机

try {
    Bitmap mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(mBitmap);
    canvas.drawColor(Color.WHITE);
    Paint paint = new Paint();
    paint.setColor(Color.BLUE);
    canvas.drawLine(10, 10, 50, 50, paint);
    
    //把Bitmap显示到控件中
    ImageView iv = findViewById(R.id.iv);
    iv.setImageBitmap(mBitmap);

    //把Bitmap转png并保存到手机
    FileOutputStream out = new FileOutputStream(FileHelper.getFileDefaultPath()+"123.png");
    mBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
    out.flush();
    out.close();
} catch (Exception e) {
   e.printStackTrace();
}

在指定图片上画图

Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.test);
Paint paint= new Paint();
paint.setColor(Color.BLUE);
canvas.drawLine(10, 10, 50, 50, paint);
Rect srcRect = new Rect(0, 0, mBitmap.getHeight(), mBitmap.getWidth());
Rect srcRect2 = new Rect(0, 0, width, height);
//Bitmap bitmap:要绘制的位图对象
//Rect src: 是对图片进行裁截,若是空null则显示整个图片
//RectF dst:是图片在Canvas画布中显示的区域
//Paint paint:画笔,这个不用多说
canvas.drawBitmap(bitmap , srcRect , srcRect2, paint);


//***canvas中引用项目中图片,并填充***
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.bg);
bitmap = Bitmap.createScaledBitmap(bitmap, width, height, true);
//Bitmap:图片对象,left:偏移左边的位置,top: 偏移顶部的位置
canvas.drawBitmap(bitmap,0,0,null);

Canvas引用项目中图片,并支持移动和缩放(以图片为中心点缩放,效果并不是以图片中心缩放)

//获取Res下的drawable或mipmap文件夹下图片资源
private Bitmap getRes(Context context,String imageName) {
    ApplicationInfo appInfo = context.getApplicationInfo();
    int resID = context.getResources().getIdentifier(imageName, "mipmap", appInfo.packageName);
    return BitmapFactory.decodeResource(context.getResources(), resID);
}
//postTranslate+postScale控制移动和缩放
//dL+pianyix_huitu/scale----这样是为了和点、线、圆等其他画的图形平移、缩放保持一致
private void addPeople(Canvas canvas,float dL,float dB){
    Bitmap bgimg = getRes(context,"user");
    Matrix matrix = new Matrix();
    matrix.postTranslate(dL+pianyix_huitu/scale,
        dB+pianyiy_huitu/scale);//平移(初始位置+移动位置)
    matrix.postScale(scale, scale);//缩放
    canvas.drawBitmap(bgimg, matrix, textPaint);
}

 Canvas中显示图片,并支持移动和缩放(第2中方法,缩放效果是以图片中心缩放)

//canvas中显示图片,并支持移动和缩放
private void drawPic(Canvas canvas,String picName,float x,float y){
	float sX = x*scale+pianyix_huitu;
	float sY = y*scale+pianyiy_huitu;
	Bitmap bitmap =choosePIC(picName);
	int width = bitmap.getWidth();
	int height = bitmap.getHeight();
	//src只是整张图片的一部分
	Rect src = new Rect((int)sX, (int)sY,width,height);
	int width2 = (int) (width*scale+pianyix_huitu);
	int height2 = (int) (height*scale+pianyiy_huitu);
	Rect dst = new Rect((int)sX, (int)sY,width2,height2);
	canvas.drawBitmap(bitmap,null,dst,picPaint);
}
//加载项目中assets中图片资源,根据自己需求也可以加载网络图片
//通过地址获取到图片的InputStream,再转成bitmap即可
private Bitmap choosePIC(String pic){
	String lowerCaseStr = pic.toLowerCase();
	Bitmap bitmap = null;
	try {
	    InputStream is = context.getAssets().open("pic/"+lowerCaseStr+".jpg");
	    if (is==null){
		is = context.getAssets().open("pic/nopic.jpg");
	    }
	    bitmap = BitmapFactory.decodeStream(is);
	} catch (IOException e) {
	    e.printStackTrace();
	}
	return bitmap;
}

人员位置(自己画的,给图形加了个边框,为了支持点击)

private void drawPeople(Canvas canvas,float x,float y,int color){
    float leftX = 500;//测试坐标X
    float topY = 200;//测试坐标Y
    float juxingW = 40;//宽
    float juxingH = 20;//高
    int strokeW = 3;//线宽
	//该图形放置到指定坐标点上边位置
    leftX = x-juxingW/2;//实际使用X
    topY = y-5-juxingH;//实际使用Y
    bkPaint.setStyle(Paint.Style.STROKE);//不加这个不显示
    bkPaint.setColor(context.getResources().getColor(R.color.myquantouming));
    canvas.drawRect(leftX*scale+pianyix_huitu,topY*scale+pianyiy_huitu,
        (leftX+juxingW)*scale+pianyix_huitu,(topY+juxingH)*scale+pianyiy_huitu,bkPaint);

	peoplePaint.setStyle(Paint.Style.STROKE);//不加这个不显示
    if (color==0){//选择颜色
        peoplePaint.setColor(context.getResources().getColor(R.color.kgl_people_me));
    }else{
        peoplePaint.setColor(context.getResources().getColor(R.color.my_blue));
    }

    peoplePaint.setStrokeWidth(strokeW);
    peoplePaint.setStyle(Paint.Style.STROKE);
    //头
    canvas.drawCircle((leftX+juxingW/4)*scale+pianyix_huitu,
        (topY+juxingH/4)*scale+pianyiy_huitu+strokeW,
        juxingH/4*scale, peoplePaint);
    //身体
    RectF oval = new RectF(leftX*scale+pianyix_huitu+strokeW,
        (topY+juxingH/2)*scale+pianyiy_huitu+strokeW,
        (leftX+juxingW/2)*scale+pianyix_huitu,
        (topY+juxingH+juxingH/2)*scale+pianyiy_huitu-strokeW);
    //定义的圆弧的形状和大小的范围
    //设置圆弧是从哪个角度来顺时针绘画的
    //设置圆弧扫过的角度
    //true:设置我们的圆弧在绘画的时候,是否经过圆形;设置空心(STROKE)时,参数true没效果
    canvas.drawArc(oval,-180,180,false,peoplePaint);
    //武器1
    Path mPath = new Path();
    float startX = (leftX+juxingW/2+juxingW/2/4)*scale+pianyix_huitu;
    float startY = (topY+juxingH/2+juxingH/2/2)*scale+pianyiy_huitu;
    float stopX = startX;
    float stopY = (topY+juxingH/2+juxingH/2/2+juxingH/2/2)*scale+pianyiy_huitu;
    mPath.moveTo(startX, startY);
    mPath.lineTo(stopX, stopY);
    mPath.close();
    canvas.drawPath(mPath, peoplePaint);
    //武器2
    mPath = new Path();
    startX = (leftX+juxingW/2+juxingW/2/4*2)*scale+pianyix_huitu;
    startY = (topY+juxingH/2)*scale+pianyiy_huitu;
    stopX = startX;
    stopY = (topY+juxingH/2+juxingH/2)*scale+pianyiy_huitu;
    mPath.moveTo(startX, startY);
    mPath.lineTo(stopX, stopY);
    mPath.close();
    canvas.drawPath(mPath, peoplePaint);
    //武器3
    mPath = new Path();
    startX = (leftX+juxingW/2+juxingW/2/4*3)*scale+pianyix_huitu;
    startY = topY*scale+pianyiy_huitu;
    stopX = startX;
    stopY = (topY+juxingH)*scale+pianyiy_huitu;
    mPath.moveTo(startX, startY);
    mPath.lineTo(stopX, stopY);
    mPath.close();
    canvas.drawPath(mPath, peoplePaint);
}

简单汽车图形(自己画的,给图形加了个边框,为了支持点击)

private void drawCar(Canvas canvas,float x,float y){
    float leftX = 500;
    float topY = 200;
    leftX = x-juxingW/2;
    topY = y-5-juxingH;
    bkPaint.setStyle(Paint.Style.STROKE);//不加这个不显示
    bkPaint.setColor(context.getResources().getColor(R.color.myquantouming));
    bkPaint.setStyle(Paint.Style.FILL);
    canvas.drawRect(leftX*scale+pianyix_huitu,topY*scale+pianyiy_huitu,
        (leftX+juxingW)*scale+pianyix_huitu,(topY+juxingH+juxingW/8)*scale+pianyiy_huitu,bkPaint);

    //车头
    bkPaint.setColor(context.getResources().getColor(R.color.myblue));
    bkPaint.setStyle(Paint.Style.FILL);
    canvas.drawRect(leftX*scale+pianyix_huitu,topY*scale+pianyiy_huitu,
        (leftX+juxingW)*scale+pianyix_huitu,(topY+juxingH)*scale+pianyiy_huitu,bkPaint);
    //轱辘
    peoplePaint.setStyle(Paint.Style.STROKE);//不加这个不显示
    peoplePaint.setColor(context.getResources().getColor(R.color.myblue));
    peoplePaint.setStyle(Paint.Style.FILL);
    canvas.drawCircle((leftX+juxingW/4)*scale+pianyix_huitu,
        (topY+juxingH)*scale+pianyiy_huitu,
        juxingW/8*scale, peoplePaint);
    canvas.drawCircle((leftX+juxingW-juxingW/4)*scale+pianyix_huitu,
        (topY+juxingH)*scale+pianyiy_huitu,
        juxingW/8*scale, peoplePaint);
}

获取控件的宽高

参考网址:Android 获取控件的宽和高_Chiclaim-CSDN博客_android 获取控件高度

ImageView test = findViewById(R.id.test);
ViewTreeObserver vto2 = draw_test.getViewTreeObserver();
vto2.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
     @Override
    public void onGlobalLayout() {
      draw_test.getViewTreeObserver().removeGlobalOnLayoutListener(this);
      width = test.getWidth();
      height = test.getHeight();
    }
});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值