16

I want to fill the color in white area for Paint based application so please give me suggestion for how to do this work..

enter image description here

Hardik Gajjar
  • 5,038
  • 8
  • 33
  • 51
  • 5
    take a look at the classic flood fill algorithm: http://en.wikipedia.org/wiki/Flood_fill – Jave Jan 10 '12 at 09:46
  • Hi, Here is the [link][1] to get the points of image. means only actual part of the image and eliminate the transparent part. but i am not able to bound the area. [1]: http://brownandroidattack.blogspot.com/2010/03/image-transparency-aka-absurd.html – Hiren Dabhi Jan 10 '12 at 09:52
  • 1
    Thanks a lot Jave for information of floodfill alogrithm – Hardik Gajjar Jan 10 '12 at 11:35
  • What tools are you using (language, image processing framework?) – mpenkov Jan 11 '12 at 02:38
  • @misha : I am using JAVA language for Android platform.. – Hardik Gajjar Jan 11 '12 at 04:26
  • you can see : http://stackoverflow.com/questions/2783204/flood-fill-using-a-stack and http://stackoverflow.com/questions/8070401/android-flood-fill-algorithm – pengwang Jan 14 '12 at 03:20
  • I want to fill it using brush... as usert touch moves... can u help me.. – Alfa Feb 19 '14 at 06:26

4 Answers4

19

I found the Solution with Flood fill algoritham

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++;
    }
}}

flood fill in android:

See this FloodFill

Community
  • 1
  • 1
Hardik Gajjar
  • 5,038
  • 8
  • 33
  • 51
  • Nice one But If i just add this algorithm to My Android app if i call the function FloodFill(with respective attributes) then will it be works ? And what should i have to give as attribute Point in this function ? – Shreyash Mahajan Mar 09 '12 at 05:30
  • thanks @Hardik, its really a nicely written algorithm. but for android phone it seem to be very slow. do you know any other way for flood filling? – Satyajitsinh Raijada Aug 11 '12 at 06:57
  • 1
    can anyone explain how to provide the targetcolor and replacement color and in which format – Pravesh Jul 17 '14 at 11:53
  • 2
    this Answer is not defined properly. You have to show the full implementation that how to use it in Android App, which works perfectly if apply. – Zia Ur Rahman Feb 27 '18 at 09:28
  • How can we use this floodfill algorithm in case of bitmap image? – Umair Apr 05 '20 at 15:51
4

Here's a quick application using Python and OpenCV (should be available on Android if you try hard enough):

"""Flood fills with random color on click.  Press `q' to exit."""
import cv
import sys
import random

TOL = 10
TOL_BGR = (TOL, TOL, TOL, 0)

def click(event,x,y,flags,im):
    if event == cv.CV_EVENT_LBUTTONDOWN:
        b,g,r = [ random.random() * 255 for i in range(3) ]
        cv.FloodFill(im, (x,y), (b,g,r,0), TOL_BGR, TOL_BGR)

im = cv.LoadImage(sys.argv[1], cv.CV_LOAD_IMAGE_COLOR)
cv.NamedWindow(__file__, 1)
cv.SetMouseCallback(__file__, click, im)
while True:
    cv.ShowImage(__file__, im)
    key = cv.WaitKey(33)
    if chr(key & 0xff) == 'q':
        break
cv.SaveImage('floodfill.png', im)

Every time the user clicks an image, the application flood-fills using the click location as a seed. The color is picked randomly. You can change the tolerances by modifying the value of TOL (or TOL_BGR). Here's the result after a couple of clicks:

enter image description here

The general algorithm is the same regardless of what technology you use.

mpenkov
  • 21,621
  • 10
  • 84
  • 126
  • could you please send the source code, because i cant understood this part – dineshprasanna Oct 23 '12 at 01:54
  • No, I will not email you teh codez. The source code is in my answer, anyway. If you don't understand anything, then please read the documentation for the relevant functions -- it is readily available. – mpenkov Oct 23 '12 at 10:07
  • If I use SVG instead of normal image what will be the approach? – isuru Feb 23 '17 at 07:31
0

1)Have the Split up image for each color portion separately with same size as actual image and other portion are transparent. 2)Have the complete image with each portion painting in different color in ur drawable folder - this is just reference image.

3) Add the all split up images in frame layout and set all split up invisible initially and set visible to actual image only

4) Hot code the color for each split up from ur reference image (step2) for Eg handSplitImageColor = green;

4) Set the listener for frame layout find out the x and y position and pass the x and y position to ur reference image (step 2) and find out the color in that particular location and match the color with step 4 and fill the particular in that image and set the visibility true for that split up image. So only that portion will get filled by color since other portion are transparent.

These are the steps i used for one of my same type of problems.

But I don't think this is the better solution but it works well for me.

Lakshmanan
  • 1,671
  • 2
  • 26
  • 42
0

after lot of searching, i came up with the following. It is fast and efficient

private void myFloodFillMethod(Point node,int targetColor, int fillColor) {
    if (targetColor != fillColor) {
        Queue<Point> queue = new LinkedList<>();
        do {
            int x = node.x;
            int y = node.y;

            while (x > 0 && getPixelColorFromArr(x - 1, y) == targetColor) {
                x--;                }
            boolean spanUp = false;
            boolean spanDown = false;

            while (x < width && checkEquality(getPixelColorFromArr(x, y),targetColor)) {
                setPixelColorFromArr(x, y, fillColor);
                if (!spanUp && y > 0
                        && checkEquality(getPixelColorFromArr(x, y - 1),targetColor)) {
                    queue.add(new Point(x, y - 1));
                    spanUp = true;
                } else if (spanUp && y > 0
                        && !checkEquality(getPixelColorFromArr(x, y - 1),targetColor)) {
                    spanUp = false;
                }
                if (!spanDown && y < height - 1
                        && checkEquality(getPixelColorFromArr(x, y + 1), targetColor)) {
                    queue.add(new Point(x, y + 1));
                    spanDown = true;
                } else if (spanDown && y < height - 1
                        && !checkEquality(getPixelColorFromArr(x, y + 1),targetColor)) {
                    spanDown = false;
                }
                x++;
            }

        } while ((node = queue.poll()) != null);
    }

}

private boolean checkEquality(int pixelColorFromArr, int targetColor) {
    return pixelColorFromArr == targetColor;
}

void fillColorInImage(Bitmap image, Point node, int targetColor, int replacementColor){

    if(targetColor ==  replacementColor) return;

    width = image.getWidth();
    height = image.getHeight();

    pixelArr = new int[width*height];

    image.getPixels(pixelArr,0,width,0,0,width,height);
    myFloodFillMethod(node,targetColor,replacementColor);

    image.setPixels(pixelArr,0,width,0,0,width,height);

}

how to call:

fillColorInImage(bmp, point, targetColor, replacementColor);

where

bmp is the bitmap of image(extract form the image view)

point is Point(x,y) where user has tapped:get it from event.getX() and event.getY()

targetColor is the color of the point: get it from bitmap.getPixel()

replacementColor is the color you want to replace it to

STG
  • 305
  • 3
  • 11