我正在寻找一种方法来实现我的图像编辑程序的工具之一,即涂料桶工具(类似于GIMP或Microsoft Paint中的工具)。
我的程序包含一个单例对象:ImagePanelSingleton
。该单例包含BufferedImage
,显示给用户。允许用户使用各种工具在图像上绘图,这使得单身人员自己#repaint()
。
到目前为止,该程序中实现的唯一工具是铅笔工具(也可在GIMP和Microsoft Paint中找到)。所有工具都实现MouseAdapter
接口,并作为侦听器添加到单例中。
我正在考虑使用非递归泛洪填充算法来执行任务。我想让这个工具快速有效地工作,所以我考虑使用#BufferedImage.getRaster()
。我不知道如何开始。
实现必须能够处理带/不带alpha通道的图像,并且对于大图像(例如1500x1500像素)必须快速。
该工具仅在用户按住Ctrl
键并左键单击图像中的一个像素时才有效。使用的颜色没有限制。它的工作方式必须与GIMP或Microsoft Paint中的paint bucket工具相同。
只有一种方法需要实施,它位于BucketTool.java
类中。
import javax.swing.*;
import java.awt.*;
public class Main extends JFrame {
public Main() {
this.setTitle("Paint Bucket Demo");
this.setLayout(new BorderLayout());
this.add(ImagePanelSingleton.INSTANCE, BorderLayout.CENTER);
this.pack();
this.setVisible(true);
}
public static void main(String[] args) {
new Main();
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.image.BufferedImage;
public class ImagePanelSingleton extends JPanel {
public BufferedImage editableImage;
public static final ImagePanelSingleton INSTANCE = new ImagePanelSingleton();
private ImagePanelSingleton() {
// initialize the BufferedImage and give it a white background
editableImage = new BufferedImage(300, 300, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d = (Graphics2D)editableImage.getGraphics();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, 300, 300);
// add some mouse motion controls to this JPanel - i.e. the mouse drawing and paint bucket tool
MouseAdapter drawTool = new PencilTool();
this.addMouseListener(drawTool);
this.addMouseMotionListener(drawTool);
MouseAdapter bucketTool = new BucketTool();
this.addMouseListener(bucketTool);
this.addMouseMotionListener(bucketTool);
}
@Override
public Dimension getPreferredSize() {
final int WIDTH = editableImage.getWidth();
final int HEIGHT = editableImage.getHeight();
return new Dimension(WIDTH + 100, HEIGHT + 100);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(editableImage, 0, 0, null);
}
}
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
public class PencilTool extends MouseAdapter {
private Point initial;
private Point end;
@Override
public void mousePressed(MouseEvent e) {
initial = e.getPoint();
}
@Override
public void mouseDragged(MouseEvent e) {
end = e.getPoint();
// draw a line
BufferedImage image = ImagePanelSingleton.INSTANCE.editableImage;
Graphics2D g2d = (Graphics2D)image.getGraphics();
g2d.setColor(Color.BLACK);
g2d.drawLine(initial.x, initial.y, end.x, end.y);
ImagePanelSingleton.INSTANCE.repaint();
// re-assign the initial point
initial = e.getPoint();
}
}
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class BucketTool extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
// do nothing if the Ctrl key is not being held down
if (!e.isControlDown())
return;
// How should I implement the rest of this method?
ImagePanelSingleton.INSTANCE.repaint();
}
}