How to scale (e.g. enlarge) custom view drawing created with fixed paths?

0

I have a CustomView with layout(l,t,r,b) in parentView.

public class MyCustomView extends View {
private Path mPath_LeftWing;
private Path mPath_RightWing;
private Paint paint_Fill_LeftWing;
private Path mPath_Head;
private Paint paint_Fill_Head;
private Path mPath_Hair;
private Paint paint_Fill_Hair;
private Path mPath_LeftEye;
private Path mPath_RightEye;
private Paint paint_Fill_Eye;
private Path mPath_LeftEyeBall;
private Path mPath_RightEyeBall;
private Paint paint_Fill_Eyeball;
private Path mPath_Mouth_Fill;
private Path mPath_Mouth_LookLine;
private Paint paint_MiddleStroke_Mouth_Lookline;
private Paint paint_Fill_Mouth;
private Paint paint_OuterStroke_All;
private Paint paint_MiddleStroke_All;

public int mLeft = 0;
public int mTop = 0;
public int mRight = 0;
public int mBottom = 0;

public MyCustomView(Context context){
    super(context);
    init();
}

When initialize this CustomView, I will calculate some paths save saved it as private variable private void init(){

    paint_OuterStroke_All = new Paint();
    paint_OuterStroke_All.setStyle(Paint.Style.STROKE);
    paint_OuterStroke_All.setStrokeJoin(Paint.Join.ROUND);

    paint_MiddleStroke_All = new Paint();
    paint_MiddleStroke_All.setStyle(Paint.Style.STROKE);
    paint_MiddleStroke_All.setStrokeJoin(Paint.Join.ROUND);

    paint_Fill_LeftWing = new Paint();
    paint_Fill_LeftWing.setStyle(Paint.Style.FILL);
    paint_Fill_LeftWing.setFlags(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
    paint_Fill_LeftWing.setStrokeJoin(Paint.Join.ROUND);


    paint_Fill_Head = new Paint();
    paint_Fill_Head.setStyle(Paint.Style.FILL);
    paint_Fill_Head.setFlags(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
    paint_Fill_Head.setStrokeJoin(Paint.Join.ROUND);


    paint_Fill_Head = new Paint();
    paint_Fill_Head.setStyle(Paint.Style.FILL);
    paint_Fill_Head.setFlags(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
    paint_Fill_Head.setStrokeJoin(Paint.Join.ROUND);

    paint_Fill_Hair = new Paint();
    paint_Fill_Hair.setStyle(Paint.Style.FILL);
    paint_Fill_Hair.setFlags(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
    paint_Fill_Hair.setStrokeJoin(Paint.Join.ROUND);


    paint_MiddleStroke_Mouth_Lookline = new Paint();
    paint_MiddleStroke_Mouth_Lookline.setStyle(Paint.Style.STROKE);
    paint_MiddleStroke_Mouth_Lookline.setStrokeJoin(Paint.Join.ROUND);

    paint_Fill_Eye = new Paint();
    paint_Fill_Eye.setStyle(Paint.Style.FILL);
    paint_Fill_Eye.setFlags(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
    paint_Fill_Eye.setStrokeJoin(Paint.Join.ROUND);

    paint_Fill_Eyeball = new Paint();
    paint_Fill_Eyeball.setStyle(Paint.Style.FILL);
    paint_Fill_Eyeball.setFlags(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
    paint_Fill_Eyeball.setStrokeJoin(Paint.Join.ROUND);

    paint_Fill_Mouth = new Paint();
    paint_Fill_Mouth.setStyle(Paint.Style.FILL);
    paint_Fill_Mouth.setFlags(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
    paint_Fill_Mouth.setStrokeJoin(Paint.Join.ROUND);

    invalidate();
}
public void finalize_beforeOnDraw(float suggested_width, float suggested_height, int start_x, int start_y){//TODO: need to finalize mBottom and mTop first before using this function
    
    float outer_Stroke_width = Math.min(suggested_width/20f,suggested_height/20f);
    float middle_Stroke_width = Math.min(suggested_width/40f,suggested_height/40f);
    float middle_Stroke_width_mouth_lookline = middle_Stroke_width*0.5f;
    paint_OuterStroke_All.setStrokeWidth(outer_Stroke_width);
    paint_OuterStroke_All.setColor(Color.WHITE);
    paint_MiddleStroke_All.setStrokeWidth(middle_Stroke_width);
    paint_MiddleStroke_All.setColor(Color.DKGRAY);
    paint_MiddleStroke_Mouth_Lookline.setStrokeWidth(middle_Stroke_width_mouth_lookline);
    paint_MiddleStroke_Mouth_Lookline.setColor(Color.DKGRAY);

    paint_Fill_LeftWing.setShader(new LinearGradient(0,suggested_height*1f/3f,0,suggested_height*2f/3f,0xffFFFF99,0xffE8E008, Shader.TileMode.CLAMP));
    paint_Fill_Head.setShader(new LinearGradient(0,suggested_height*1f/3f,0,suggested_height*2f/3f,0xffFFCC99,0xffCC6600, Shader.TileMode.CLAMP));
    paint_Fill_Hair.setShader(new LinearGradient(0,suggested_height*1f/8f,0,suggested_height*3f/8f,0xff66FFCC,0xff00CC00, Shader.TileMode.CLAMP));
paint_Fill_Eye.setShader(new LinearGradient(0,suggested_height*2f/5f,0,suggested_height*3.3f/5f,0xff202020,0xff000000, Shader.TileMode.CLAMP));
paint_Fill_Eyeball.setShader(new LinearGradient(0,suggested_height*2f/5f,0,suggested_height*3.3f/5f,0xffFFFFFF,0xffC0C0C0, Shader.TileMode.CLAMP));
paint_Fill_Mouth.setShader(new LinearGradient(0,suggested_height*1f/2f,0,suggested_height*3f/4f,0xffFFFF66,0xffCCCC00, Shader.TileMode.CLAMP));

mLeft = start_x;
mTop = start_y;
mRight = mLeft + (int) (Math.ceil(suggested_width) + 0.5f);
mBottom = mTop + (int) (Math.ceil(suggested_height) + 0.5f);
layout(mLeft,mTop,mRight,mBottom);

//TODO:many paths calculation using path.moveTo , path.lineTo, path.quadTo
...  

}

@Override
protected void onDraw(Canvas canvas) {

    super.onDraw(canvas);

    //TODO: Draw Layer0
    canvas.drawPath(mPath_LeftWing,paint_OuterStroke_All);
    canvas.drawPath(mPath_RightWing,paint_OuterStroke_All);
    canvas.drawPath(mPath_Head, paint_OuterStroke_All);
    canvas.drawPath(mPath_Hair,paint_OuterStroke_All);

    //TODO: Draw Layer1
    canvas.drawPath(mPath_LeftWing,paint_MiddleStroke_All);
    canvas.drawPath(mPath_LeftWing,paint_Fill_LeftWing);
    canvas.drawPath(mPath_RightWing,paint_MiddleStroke_All);
    canvas.drawPath(mPath_RightWing,paint_Fill_LeftWing);
    canvas.drawPath(mPath_Hair,paint_MiddleStroke_All);
    canvas.drawPath(mPath_Hair,paint_Fill_Hair);

    //TODO: Draw Layer2
    canvas.drawPath(mPath_Head, paint_MiddleStroke_All);
    canvas.drawPath(mPath_Head, paint_Fill_Head);

    //TODO: Draw Layer3
    canvas.drawPath(mPath_LeftEye,paint_Fill_Eye);
    canvas.drawPath(mPath_RightEye,paint_Fill_Eye);
    canvas.drawPath(mPath_LeftEyeBall,paint_Fill_Eyeball);
    canvas.drawPath(mPath_RightEyeBall,paint_Fill_Eyeball);
    canvas.drawPath(mPath_Mouth_Fill,paint_Fill_Mouth);

    //TODO: Draw Layer4
    canvas.drawPath(mPath_Mouth_LookLine,paint_MiddleStroke_Mouth_Lookline);




}

Aim: I want to enlarge this CustomView Drawing into scaleX and scaleY = 2.0f, however, as my paint.setShader LinearGradient is depend not from 0,0 to 0,suggestedHeight, but maybe e.g. 0,0.3fsuggestHeight to 0,0.5fsuggestHeight sometimes or whatever, scaling a path by Matrix is not a good solution as the paint will take no effect when I use canvas.draw(path_xx,paint_yy).

I have browsed a website http://icrobotics.co.uk/wiki/index.php/Android_101:_implementing_a_drawing_canvas

It uses

matrix.postScale(scale, scale, mid.x, mid.y);

then

public void onDraw(Canvas canvas){
// ...
canvas.drawBitmap(kangoo,matrix,paint);
}

But my drawings are smooth path, canvas.drawBitmap seems will not make a smooth enlarged drawing. What should I do?

android
canvas
path
scaling
asked on Stack Overflow Jul 29, 2020 by Raii • edited Jul 29, 2020 by Felix

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0