Android - Fill path with color

I am trying to draw a heart shape using Path in Android. The code is as follows:

@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // Fill the canvas with background color canvas.drawColor(Color.WHITE); // paint.setShader(null); // Defining of the heart path starts path.moveTo(left + WIDTH / 2, top + HEIGHT / 4); // Starting point // Create a cubic Bezier cubic left path path.cubicTo(left+WIDTH/5,top, left+WIDTH/4,top+4*HEIGHT/5, left+WIDTH/2, top+HEIGHT); // This is right Bezier cubic path path.cubicTo(left + 3 * WIDTH / 4, top + 4 * HEIGHT / 5, left + 4 * WIDTH / 5, top, left + WIDTH / 2, top + HEIGHT / 4); paint.setShader(new LinearGradient(0, canvas.getHeight()/4, canvas.getWidth(), canvas.getHeight()/4, new int[]{Color.RED, Color.YELLOW, Color.GREEN}, new float[]{0, 0.6f, 1}, Shader.TileMode.CLAMP)); canvas.drawPath(path, paint); heart_outline_paint.setColor(getResources().getColor(R.color.heart_outline_color)); // Change the boundary color heart_outline_paint.setStrokeWidth(4); heart_outline_paint.setStyle(Paint.Style.STROKE); canvas.drawPath(path, heart_outline_paint); } 

I can draw a heart without any problems, and I can fill the color inside the heart using the Fill option in Paint. But I must be able to fill my heart dynamically according to some data, and it cannot be filled completely all the time. The following has been achieved so far:

Color filled heart shape

I did an extensive search and came across a lot similar to this. Some of them include:

I also came across the concept of converting canvas to a bitmap and filling in colors inside a bitmap using the Flood Fill Algorithm , which allows users to fill colors inside a bitmap. However, I do not want the bitmap to fill the color, touching his heart, but filling it with the click of a button.

I thought that gradually filling the circle from bottom to top android would help me, but it uses the circle and I am not good at Canvas, which makes me very weak when adapting the circle code to this form.

If anyone has any ideas or any ideas on how to achieve this, this will be really helpful. Greetings. Thank you in advance.

PS: I also tried some tricks using setShader in Paint, but nothing would give me what I want.

EDIT:

I just stumbled upon the idea of ​​drawing a rectangle over a heart with a different color, the same as on the background of the canvas, so that it looks half full !! I am still working on this idea and do not know how much it will be for me. If anyone has a better idea, you will be very pleased.

enter image description here

+6
source share
2 answers

I used the clipPath function available in Canvas to achieve what I need. I draw the heart with the method above and draw a rectangle above it, and I use the clipPath function to cut out the area that is outside the heart.

  public static double filled_amount = .90; path.moveTo(left_x_moveto, left_y_moveto); path.cubicTo(left_x1, left_y1, left_x2, left_y2, left_x3, left_y3); path.cubicTo(right_x2, right_y2, right_x1, right_y1, left_x_moveto, left_y_moveto); path.close(); Rect rect = new Rect((int)(canvas.getWidth()*.10),(int)(canvas.getHeight()*filled_amount),(int) canvas.getWidth(), (int) canvas.getHeight()); canvas.clipPath(path); paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.FILL); canvas.drawPath(path, paint); canvas.drawRect(rect, rect_paint); heart_outline_paint.setColor(getResources().getColor(R.color.heart_outline_color)); // Change the boundary color heart_outline_paint.setStrokeWidth(15); heart_outline_paint.setStyle(Paint.Style.STROKE); canvas.drawPath(path, heart_outline_paint); 

This will give me the desired result of heart filling. Changing the dynamic value of filled_amount and calling invalidate() will make it look like the heart is being filled dynamically.

@ Henry's answer may be the best, but it did the trick for me, and I don’t look deep into the edges, so a few zigzags here and there everything is in order.

+1
source

You can use Bitmap Masking to get a partially filled Heart. What you ideally do here is use one bitmap to mask another.

In your case, you may have a filled rectangle on the canvas, and then you have a heart shape in the new bitmap to act like a mask. Then you can dynamically change the filling of the heart by changing the height of the background of the rectangle.

Please note: fooobar.com/questions/160659 / .... This contains a partial fill implementation of Star . The idea is the same.

+1
source

All Articles