中国优质的IT技术网站
专业IT技术创作平台
IT职业在线教育平台
本文利用FloodFill算法实现PixelMap的填色(油漆桶)效果。
关于FloodFill算法的介绍,请查看这篇文章:https://blog.csdn.net/lion19930924/article/details/54293661
下面介绍鸿蒙系统下填色功能的实现:
定义一个算法类,用于实现FloodFill算法:
public class FloodFillAlgorithm { private PixelMap fillBitmap; private int width; private int height; private boolean isFillColor = true; private int maxStackSize = 500; private int[] xstack = new int[maxStackSize]; private int[] ystack = new int[maxStackSize]; private int stackSize; public FloodFillAlgorithm(PixelMap fillBitmap) { this.fillBitmap = fillBitmap; width = fillBitmap.getImageInfo().size.width; height = fillBitmap.getImageInfo().size.height; } public int getColor(int x, int y) { return fillBitmap.readPixel(new Position(x, y)); } public void setColor(int x, int y, int newColor) { fillBitmap.writePixel(new Position(x, y), newColor); } public boolean isFill() { return isFillColor; } public void floodFillScanLineWithStack(int x, int y, int newColor, int oldColor) { if (oldColor == newColor) { System.out.println("do nothing !!!, filled area!!"); return; } emptyStack(); int y1; boolean spanLeft, spanRight; push(x, y); while (true) { x = popx(); if (x == -1) return; y = popy(); y1 = y; while (y1 >= 0 && getColor(x, y1) == oldColor) y1--; // go to line top/bottom y1++; // start from line starting point pixel spanLeft = spanRight = false; while (y1 < height && getColor(x, y1) == oldColor) { setColor(x, y1, newColor); if (!spanLeft && x > 0 && getColor(x - 1, y1) == oldColor)// just keep left line once in the stack { push(x - 1, y1); spanLeft = true; } else if (spanLeft && x > 0 && getColor(x - 1, y1) != oldColor) { spanLeft = false; } if (!spanRight && x < width - 1 && getColor(x + 1, y1) == oldColor) // just keep right line once in the stack { push(x + 1, y1); spanRight = true; } else if (spanRight && x < width - 1 && getColor(x + 1, y1) != oldColor) { spanRight = false; } y1++; } } } private void emptyStack() { while (popx() != -1) { popy(); } stackSize = 0; } final void push(int x, int y) { stackSize++; if (stackSize == maxStackSize) { int[] newXStack = new int[maxStackSize * 2]; int[] newYStack = new int[maxStackSize * 2]; System.arraycopy(xstack, 0, newXStack, 0, maxStackSize); System.arraycopy(ystack, 0, newYStack, 0, maxStackSize); xstack = newXStack; ystack = newYStack; maxStackSize *= 2; } xstack[stackSize - 1] = x; ystack[stackSize - 1] = y; } final int popx() { if (stackSize == 0) return -1; else return xstack[stackSize - 1]; } final int popy() { int value = ystack[stackSize - 1]; stackSize--; return value;
调用方式如下:
FloodFillAlgorithm floodFillAlgorithm = new FloodFillAlgorithm(pixelBitmap); floodFillAlgorithm.floodFillScanLineWithStack(1, 1, Color.RED.getValue(), Color.GREEN.getValue());
效果如下:至此,填色(油漆桶)效果已实现
微信扫码分享