Как заполнить цвет изображения в определенной области?

Я хочу заполнить цвет в белой области для приложения на основе краски поэтому, пожалуйста, дайте мне предложение о том, как это сделать.

enter image description here

Ответ 1

Я нашел решение с алгоритмом заполнения флуда

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

заливка заливки в android:

Смотрите FloodFill

Ответ 2

Здесь быстрое приложение, использующее Python и OpenCV (должно быть доступно на Android, если вы достаточно стараетесь):

"""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)

Каждый раз, когда пользователь нажимает на изображение, приложение заливает поток, используя местоположение щелчка в качестве семени. Цвет выбирается случайным образом. Вы можете изменить допуски, изменив значение TOL (или TOL_BGR). Вот результат после нескольких кликов:

enter image description here

Общий алгоритм тот же, независимо от того, какую технологию вы используете.

Ответ 3

1) Разделите изображение для каждой цветной части отдельно с тем же размером, что и фактическое изображение, а другая часть прозрачна. 2) У вас есть полное изображение с каждой порцией, покраской в ​​другой цвет в папке ur drawable - это всего лишь ссылочное изображение.

3) Добавьте все расщепленные изображения в макете кадра и сначала установите все расщепленные невидимые и установите только видимое изображение

4) Горячий код цвета для каждого разделить от ур эталонного изображения (step2), например, для handSplitImageColor = зеленый;

4) Установить слушатель для компоновки кадра выяснить, х и у позиции и передать й и у позиции на уры опорного изображения (этап 2) и выяснить, цвет в этом конкретном месте и соответствовать цвету с шагом 4 и заполните конкретное изображение и установите видимость для этого разделенного изображения. Таким образом, только эта часть будет заполнена цветом, поскольку другая часть прозрачна.

Это шаги, которые я использовал для одного из моих проблем.

Но я не думаю, что это лучшее решение, но оно хорошо работает для меня.

Ответ 4

после долгих поисков я придумал следующее. Это быстро и эффективно

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);

}

как позвонить:

fillColorInImage(bmp, point, targetColor, replacementColor);

где

bmp - это растровое изображение (извлечение из вида изображения)

point - это точка (x, y), где пользователь нажал: получить ее из event.getX() и event.getY()

targetColor - это цвет точки: получите его из bitmap.getPixel()

replacementColor - это цвет, на который вы хотите заменить