替换图像中一种颜色的最快方法

时间:2015-12-28 17:48:29

标签: java image colors pixels

所以我需要用另一种颜色替换图像中的颜色。我考虑过迭代所有像素,如果它们与指定的颜色匹配,则逐个更改它们,但这种方法太慢了。我已经开始使用ColorModels,但我并不是真的理解它,尽管它看起来正是我需要的。

我一直在玩这个例子,我只是说,结果颜色模型只有4位(我甚至可能错了)。 How to replace color with another color in BufferedImage

无论如何,过去两天我一直在与这个例子搏斗,很少展示。有人可以告诉我如何改变这个

enter image description here

进入此...(红色已变为蓝色)

enter image description here

请帮助,我真的坚持这个。我想使用ColorModels,但是如果有另一个选项没有涉及迭代像素并且非常快,请告诉我。

1 个答案:

答案 0 :(得分:0)

我不知道这对你的目的有多大用处,我不知道“足够快”的速度有多快,但这是我想到的一些相对较快的代码(花了8ms)测试运行我只是用它做了。)

//Demonstration main method
public static void main(String[] args) {
        BufferedImage img = new BufferedImage(900, 900, BufferedImage.TYPE_INT_RGB);
        initImage(img);
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JPanel panel = new JPanel() {
                public void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    g.drawImage(img, 0, 0, null);
                }
            };
            panel.setPreferredSize(new Dimension(img.getWidth(), img.getHeight()));
            frame.add(panel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
            new Thread( () -> {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                iterateThroughColorRaster(img);
                panel.repaint();
            }).start();
        });
    }

 //Actual code you were asking for a solution to
public static int testColour(int rgb) {
    int red = (rgb >> 16) & 0xFF;
    int green = (rgb >> 8) & 0xFF;
    int blue = rgb & 0xFF;
    int newRed;
    int newGreen = green;
    int newBlue;
    //This could be changed to a "threshold" if you don't want only exact red  colours to be changed, e.g. (if red > 230 && others < 30) or similar
    if (red == 255 && blue == 0 && green == 0) {
        newRed = 0;
        newBlue = 255;
    } else {
        newRed = red;
        newBlue = blue;
    }
    return (newRed << 16) | (newGreen << 8) | newBlue;
}

//Create some colours
private static void initImage(BufferedImage img) {
    int[] initialBuf = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
    Random rand = new Random();
    for (int i = 0; i < initialBuf.length; i++) {
        if (rand.nextInt(3) == 2) {
            initialBuf[i] = toRGB(255, 0, 0);
        } else {
            initialBuf[i] = toRGB(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
        }
    }
}

//Get the raster array, iterate through, checking each pixel
public static void iterateThroughColorRaster(BufferedImage img) {
    long before = System.currentTimeMillis();
    int[] buf = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
    buf = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
    for (int i = 0; i < buf.length; i++) {
        buf[i] = testColour(buf[i]);
    }
    System.out.println(System.currentTimeMillis() - before);
}


//For convenience
public static int toRGB(int red, int green, int blue) {
    return (red << 16) | (green << 8) | blue;
}