I am making a drawing app for android and I need some help adding a fill tool.
I want the tool to flood fill, and to behave like it would in Microsoft Paint, but on a phone.
I have a custom view that draws a path on a canvas. I draw different paths for different pens and brushes, and I allow users to pick line thickness and color.
When I do:
paint.setStyle(Paint.Style.FILL);
and I paint, I don't get a fill how I want.
I have gotten some suggestions to use the "Flood Fill Algorithm", but I can't figure out how to implement it in my code.
Where could I go to see an example of what I am trying to do? Does anyone have sample code to show me how I could make the tool work with my android view?
EDIT:
CartoonView.java:
public class CartoonView extends View {
ArrayList<Paint> paints = new ArrayList<Paint>();
ArrayList<Path> paths = new ArrayList<Path>();
int color;
int thickness;
boolean pencilSelected;
public boolean isPencilSelected() {
return pencilSelected;
}
public void setPencilSelected(boolean pencilSelected) {
this.pencilSelected = pencilSelected;
}
public ArrayList<Paint> getPaints() {
return paints;
}
public void setPaints(ArrayList<Paint> paints) {
this.paints = paints;
}
public ArrayList<Path> getPaths() {
return paths;
}
public void setPaths(ArrayList<Path> paths) {
this.paths = paths;
}
public int getThickness() {
return thickness;
}
public int getColor() {
return color;
}
public CartoonView(Context context, AttributeSet attrs) {
super(context, attrs);
color = Color.BLACK;
thickness = 3;
pencilSelected = true;
createPaint();
}
@Override
protected void onDraw(Canvas canvas) {
for (Path path : paths) {
canvas.drawPath(path, paints.get(paths.indexOf(path)));
}
}
public void setPaintColor(int newColor) {
color = newColor;
createPaint();
}
public void setPaintThickness(int newThickness) {
thickness = newThickness;
createPaint();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (this.isEnabled()) {
Path path;
if (paths.size() == 0) {
path = new Path();
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(5f);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setColor(color);
paint.setStrokeWidth(thickness);
thickness = (int) paint.getStrokeWidth();
paths.add(path);
paints.add(paint);
} else {
path = paths.get(paths.size() - 1);
}
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
path.moveTo(eventX, eventY);
return true;
case MotionEvent.ACTION_MOVE:
path.lineTo(eventX, eventY);
break;
default:
return true;
}
invalidate();
}
return true;
}
public void createPaint() {
Path path = new Path();
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(5f);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setColor(color);
paint.setStrokeWidth(thickness);
paths.add(path);
paints.add(paint);
}
public void clearView(){
paths.clear();
paints.clear();
invalidate();
}
}
Use Lunapic.com's Paint Bucket Tool to fill in areas of an image with color or patterns. Click on the area of the image you want to fill in! You can also try Painter (new) for all online painter needs.
Q #1) Is Procreate available for Android? Answer: Procreate is an amazing app that is used for digital drawing and painting. However, it is only available for iPhone and iPad, and not Android devices.
PhotoDirector is the best app to use to turn photos into sketches, mainly because of its ease of use. Just select a picture and an effect to transform an image into a drawing. Turning photos into sketches is fun with PowerDirector because it provides a simple user interface and gives you plenty of creative options.
Picsart Color is a drawing app where you can paint, color, and draw digital illustrations. Drawing and creating digital art has never been easier and more fun!
I completely agree with the some of the commentators who said about Flood Fill Algorithm.
Below is the function which works as what you want. Just try it:
private void FloodFill(Bitmap bmp, Point pt, int targetColor, int replacementColor){
Queue<Point> q = new LinkedList<Point>();
q.add(pt);
while (q.size() > 0) {
Point n = q.poll();
if (bmp.getPixel(n.x, n.y) != targetColor)
continue;
Point w = n, e = new Point(n.x + 1, n.y);
while ((w.x > 0) && (bmp.getPixel(w.x, w.y) == targetColor)) {
bmp.setPixel(w.x, w.y, replacementColor);
if ((w.y > 0) && (bmp.getPixel(w.x, w.y - 1) == targetColor))
q.add(new Point(w.x, w.y - 1));
if ((w.y < bmp.getHeight() - 1)
&& (bmp.getPixel(w.x, w.y + 1) == targetColor))
q.add(new Point(w.x, w.y + 1));
w.x--;
}
while ((e.x < bmp.getWidth() - 1)
&& (bmp.getPixel(e.x, e.y) == targetColor)) {
bmp.setPixel(e.x, e.y, replacementColor);
if ((e.y > 0) && (bmp.getPixel(e.x, e.y - 1) == targetColor))
q.add(new Point(e.x, e.y - 1));
if ((e.y < bmp.getHeight() - 1)
&& (bmp.getPixel(e.x, e.y + 1) == targetColor))
q.add(new Point(e.x, e.y + 1));
e.x++;
}
}}
You can also read some information regarding Flood fill on link: Link1, Link2 and Link3
Hope you got answer to your question. Please let me know i can help you in another way or you have doubt in above answer.
Enjoy Coding... :)
Updated with more information:
Above functiona will work on bases of the FloodFill algorithm. What it will exactly do is, It will detect the pixcel point and color on that pixel whereever you touch. Then it will fill the color by pixel to pixel by the selected color till any pixel dont have different color then it have currently.
I hope it will help you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With