问题
I have floodfill algorithm and I want add to this mouseClicked, but I dont know how becouse I have many errors.
Here is my code. I want get the x,y possition from mouseClicked and give it to "floodFill(image,x,y, yellow);"
Can anyone help me? thanks
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
class AnimationFiller
{
// draw a black square with a pen width of 1 pixels
static void drawSquare(BufferedImage image)
{
java.awt.Graphics2D gr=(java.awt.Graphics2D) image.getGraphics();
gr.setColor(new java.awt.Color(0,0,0)); // black
gr.setStroke(new java.awt.BasicStroke(1)); // set pen width to 1 pixel
gr.drawRect(0, 0, 296, 264); // (x,y,w,h);
}
// implements the flood fill algorithm
public static void floodFill(BufferedImage image, int x,int y, int fillColor)
{
java.util.ArrayList<Point> examList=new java.util.ArrayList<>();
int initialColor=image.getRGB(x,y);
examList.add(new Point(x,y));
while (examList.size()>0)
{
Point p = examList.remove(0); // get and remove the first point in the list
if (image.getRGB(p.x,p.y)==initialColor)
{
x = p.x; y = p.y;
image.setRGB(x, y, fillColor); // fill current pixel
examList.add(new Point(x-1,y)); // check west neighbor
examList.add(new Point(x+1,y)); // check east neighbor
examList.add(new Point(x,y-1)); // check north neighbor
examList.add(new Point(x,y+1)); // check south neighbor
}
}
}
public static int packRgb(int r,int g,int b)
{
return (r*256+g)*256+b;
}
static JLabel _imageLabel;
public static void main(String[] args) throws Exception
{
// read bmp image from file
final BufferedImage image = ImageIO.read(new File("picture.bmp"));
drawSquare(image);
final JLabel imageLabel = new JLabel();
_imageLabel = imageLabel; // make it global
imageLabel.setIcon(new ImageIcon(image));
javax.swing.JFrame window = new javax.swing.JFrame();
window.setResizable(false);
window.setTitle("Kolorowanka");
window.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
window.add(imageLabel);
window.pack();
window.setVisible(true);
// fill the image with yellow color
final int yellow = packRgb(255,255,0);
imageLabel.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
floodFill(image, e.getX(), e.getY(), yellow);
imageLabel.setIcon(new ImageIcon(image));
}
});
}
}
回答1:
You can add mouseClicked event in this way:
imageLabel.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
floodFill(image, e.getX(), e.getY(), yellow);
}
});
If you want use some fields from outside of the anonymous class you have to define it as final. For example:
final BufferedImage image = ...
And
final int yellow = packRgb(255, 255, 0);
Please, read about final field before writing next parts of your project. Example sources:
- Use final liberally
- What is final in Java? Final variable , Method and Class Example
- Thread-safety with the Java final keyword
- Java theory and practice: Is that your final answer?
回答2:
This is a implementation of a scanline flood fill algorithm which I wrote a couple of months ago.
boundaries
is a stack, startX
, startY
are the cordinates of the starting point.
pixels
array contain the rgb value of all the pixels in the in the image. The array was obtained using PixelGrabber
on the source image.
The use of all other variables are implied.
boundaries.push(new Point(startX,startY));
//Now we have the starting positions for coloring in the above and lower lines
//coloring is done in right directions only
while(!boundaries.isEmpty()) //Loop as many times till no starting positions are found
{
//Now begin coloring
Point pt=boundaries.pop();
//This is the starting point for coloring towards right direction
int x=pt.x;
int y=pt.y;
//First go as far left as possible until a different colored pixel is found
while(x>=0)
{
if(pixels[y*WIDTH+x]!=pickPointPreviousColor) break;
x--;
}
x++;
//Now extend right
while (x<=WIDTH)
{
if(pixels[y*WIDTH+x]==pickPointPreviousColor)
pixels[y*WIDTH+x]=colorToFill;
else
{
upperLineCountingStarted = false;
lowerLineCountingStarted=false;
break;
}
if(y>0 && upperLineCountingStarted==false && pixels[(y-1)*WIDTH+x]==pickPointPreviousColor)
{
boundaries.push(new Point(x,y-1));
upperLineCountingStarted=true;
}
else if(y>0 && upperLineCountingStarted==true && pixels[(y-1)*WIDTH+x]!=pickPointPreviousColor)
upperLineCountingStarted=false;
if(y<HEIGHT && lowerLineCountingStarted==false && pixels[(y+1)*WIDTH+x]==pickPointPreviousColor)
{
boundaries.push(new Point(x,y+1));
lowerLineCountingStarted=true;
}
else if(y<HEIGHT && lowerLineCountingStarted==true && pixels[(y+1)*WIDTH+x]!=pickPointPreviousColor)
lowerLineCountingStarted=false;
x++;
}
}
来源:https://stackoverflow.com/questions/14672861/how-to-add-mouseclicked-to-script