我正在使用 Java 制作一个图像编辑应用程序,并且想要制作一个按颜色选择工具。按颜色选择工具使我的变量
selection
(Area
的子类)根据所选图像中的像素是否为特定颜色(int
)来突出显示它们。在此代码片段中,selectedImage
是用于创建Area
的BufferedImage。
int selectedColor = selectedImage.getRGB(...based on MouseEvent...);
for(int x = 0 ; x < selectedImage.getWidth() ; x++){
for(int y = 0 ; y < selectedImage.getHeight() ; y++){
if(selectedImage.getRGB(x, y) == selectedColor){
selection.add(new Area(new Rectangle(x, y, 1, 1)));
}
}
}
我在 StackOverflow 或 Oracle 文档中没有真正找到任何有用的内容来解决我的问题。我找到了
LookUpOp
,它几乎能够满足我的需求,但它只能通过转换 BufferedImage
来工作,而我无法将其变成 Area
。
此代码可以工作,但是速度太慢,无法成为使该工具工作的可接受方式。
我编写了一个脚本来对此进行分析。我发现与更新区域相比,RGB 查找和迭代顺序无关紧要。正如您所建议的 Path2D 可以显着改善结果。
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Area;
import java.awt.geom.Path2D;
import java.awt.image.BufferedImage;
public class PixelPaths {
static class Result{
Path2D p = new Path2D.Double();
public void add(Shape s){
p.append(s, false);
}
public Area build(){
return new Area(p);
}
}
static int w = 512;
static int h = 512;
public static void main(String[] args){
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D)img.getGraphics();
g.setColor(Color.BLUE);
g.fillRect(w/10, h/10, w/8, h/8);
g.fillRect( w/4, h/4, w/2, h/2);
Result result = new Result();
long start = System.nanoTime();
int chosen = img.getRGB(w/2, h/2);
for(int j = 0; j<h; j++){
for(int i = 0; i<w; i++){
int p = img.getRGB(i, j);
if(p == chosen){
result.add( new Area(new Rectangle(i, j, 1, 1)));
}
}
}
Area finished = result.build();
long finish = System.nanoTime();
System.out.println("iterated in: " + (finish - start)/1e9 + " seconds");
g.setColor(Color.RED);
g.draw(finished);
g.dispose();
JLabel label = new JLabel(new ImageIcon(img));
JFrame frame = new JFrame("Vector to Path");
frame.add(label);
frame.pack();
frame.setVisible(true);
}
}
512x512 的运行时间从 4.5 秒缩短到不到一秒。它似乎随着更大的图像线性缩放。 2048 x 2048 大约需要 1.3 秒。
更改迭代顺序,即在外循环中迭代 j 并没有对查找速度产生任何影响,但在创建区域之后却起到了作用。