我想在基于Paint的应用程序中为白色区域填充颜色,所以请给我建议如何完成这项工作。
我想在基于Paint的应用程序中为白色区域填充颜色,所以请给我建议如何完成这项工作。
我用泛洪算法找到了解决方案
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。
以下是使用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)
1) 将每个颜色部分拆分为单独的图像,大小与实际图像相同,其他部分为透明。 2) 在drawable文件夹中有完整的图像,每个部分都用不同的颜色绘制-这只是参考图像。
3) 将所有拆分的图像添加到帧布局中,并最初将所有拆分设置为不可见,仅将实际图像设置为可见
4) 从您的参考图像(步骤2)中为每个拆分的代码热编码颜色,例如handSplitImageColor = green;
5) 为帧布局设置侦听器,找出x和y位置,并将x和y位置传递给您的参考图像(步骤2),找出该特定位置的颜色,并将颜色与步骤4匹配,填充该图像中的特定部分并将可见性设置为true。因此,只有该部分会被颜色填充,因为其他部分是透明的。
这些是我用于解决同类型问题的步骤。
但我认为这不是更好的解决方案,但它对我很有效。
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
是用户点击的点 Point(x,y):从 event.getX()
和 event.getY()
获取
targetColor
是该点的颜色:从 bitmap.getPixel()
获取
replacementColor
是您想要替换的颜色