0

私が持っている行クラスを使用して、プログラム用の塗りつぶしツールを作成したかったのです。私の塗りつぶしバケットは、たとえば、領域を塗りつぶすために描画する必要があるすべての線を記録します。

http://i.imgur.com/Cywh8xU.png - この画像では、クリックした点は赤い円で、各線 (始点と終点) に対して 2 つの点が見つかります。もちろんすべての線を描いたわけではありませんが、それが私が持っているものの基本的なコンセプトです。

私が直面している問題は、画像がこのようになってしまい、その理由が分からないことです。 http://i.imgur.com/IXHgEf2.jpg

これまでのすべての行を見つけるための私のコードは次のとおりです。

パブリッククラスFillBucket{

private BufferedImage image;
private Fill currentFill;
private Line currentLine;

private Queue<Point> pointsToVisit;

@Override
public void mousePressed(Point point) {
    super.mousePressed(point);

    if(pointIsOnCanvas(point)) {
        image = new BufferedImage(getCanvas().getPreferredSize().width, getCanvas().getPreferredSize().height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = (Graphics2D) image.getGraphics();
        getCanvas().paint(g2);

        currentFill = new Fill(getColor());
        pointsToVisit = new LinkedList<>();
        createPoints(point, image.getRGB(point.x, point.y));

        getCanvas().addDrawable(currentFill);
        getCanvas().repaint();
    }
}

private void createPoints(Point clickedPoint, int clickedColor) {
    pointsToVisit.add(clickedPoint);

    while(!pointsToVisit.isEmpty()) {
        Point testPoint = pointsToVisit.poll();

        if(testPoint.x > 0 && testPoint.x < image.getWidth() && testPoint.y > 0 && testPoint.y < image.getHeight() 
                && image.getRGB(testPoint.x, testPoint.y) == clickedColor) {
            while(testPoint.x > 0 && image.getRGB(testPoint.x, testPoint.y) == clickedColor) {
                testPoint.x--;
            }
            currentLine = new Line(getColor(), 5);
            currentLine.addPoint(new Point(testPoint));
            while(testPoint.x < image.getWidth() && image.getRGB(testPoint.x, testPoint.y) == clickedColor) {
                pointsToVisit.add(new Point(testPoint.x, testPoint.y+1));
                pointsToVisit.add(new Point(testPoint.x, testPoint.y-1));

                image.setRGB(testPoint.x, testPoint.y, getColor().getRGB());
                testPoint.x++;
            }
            currentLine.addPoint(new Point(testPoint));
            currentFill.addLine(currentLine);
        }
    }
}

}

これが私のラインクラスの基本です:

public class Line {
private List<Point> points;
private int width;

/**
 * Create a Line
 * @param color - The color of the line
 * @param width - The width of the line
 */
public Line(Color color, int width){
    points = new LinkedList<>();
    setColor(color);
    setWidth(width);
}

/**
 * Add a Point to the Line
 * @param p - The Point to add to the Line 
 */
public void addPoint(Point p) {
    points.add(p);
}

@Override
public void draw(Graphics2D g2) {
    super.draw(g2);
    g2.setStroke(new BasicStroke(getWidth(), BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    for(int i=1; i<points.size(); i++)
        g2.drawLine(points.get(i-1).x, points.get(i-1).y, points.get(i).x, points.get(i).y);
}

}

そして、ここに私の Fill クラスがあります:

public class Fill{

List<Line> lines;

/**
 * Create a Fill
 * @param color - The Color of the Fill
 */
public Fill(Color color){
    lines = new LinkedList<>();
    setColor(color);
}

/**
 * Add a Line to the Fill
 * @param l - The Line to add
 */
public void addLine(Line l) {
    lines.add(l);
}

@Override
public void draw(Graphics2D g2) {
    super.draw(g2);
    for(Line l: lines) {
        l.draw(g2);
    }
}

助けていただければ幸いです、ありがとう。

4

1 に答える 1

1

createPoints(...)関数を次のように変更する必要があります。

private void createPoints(Point clickedPoint, int clickedColor) {
    pointsToVisit.add(clickedPoint);

    while(!pointsToVisit.isEmpty()) {
        Point testPoint = pointsToVisit.poll();

        if(testPoint.x >= 0 && testPoint.x < image.getWidth() && testPoint.y >= 0 && testPoint.y < image.getHeight() 
            && image.getRGB(testPoint.x, testPoint.y) == clickedColor) {
            while(testPoint.x > 0 && image.getRGB(testPoint.x-1, testPoint.y) == clickedColor) {
                testPoint.x--;
            }
            currentLine = new Line(getColor(), 5);
            currentLine.addPoint(new Point(testPoint));

            pointsToVisit.add(new Point(testPoint.x, testPoint.y+1));
            pointsToVisit.add(new Point(testPoint.x, testPoint.y-1));

            image.setRGB(testPoint.x, testPoint.y, getColor().getRGB());

            while(testPoint.x < image.getWidth()-1 && image.getRGB(testPoint.x+1, testPoint.y) == clickedColor) {
                pointsToVisit.add(new Point(testPoint.x, testPoint.y+1));
                pointsToVisit.add(new Point(testPoint.x, testPoint.y-1));

                image.setRGB(testPoint.x, testPoint.y, getColor().getRGB());
                testPoint.x++;
            }
            currentLine.addPoint(new Point(testPoint));
            currentFill.addLine(currentLine);
        }
    }
}

(画像の左上隅をクリックできるように条件にいくつかの=- 記号を散りばめ、次に説明するバグを修正するために条件にs とs をいくつか散りばめました)if+1-1while

基本的に、最初のwhileループの後、画像の左端にいる場合はすべてtestPoint正常に動作するか、clickedColorと等しくない最初のピクセルを指しています。 while ループはすぐに終了します。

ところで:すでに塗りつぶしの色に設定されているポイントをクリックすると(つまり、場合clickedColor == getColor())、コードはおそらくロックアップします。

于 2013-03-06T06:41:04.703 に答える