我需要切换图像的RGB通道的开/关,但我卡住了,而且我的代码有问题。
你能帮我弄清楚如何以正确的方式做到这一点吗?这是我的代码:
当3个复选框中的1个已更改其状态并提供true == selected
public void channels(boolean red, boolean green, boolean blue) {
if (this.img != null) {// checks if the image is set
char r = 0xFF, g = 0xFF, b = 0xFF;
if (red == false) {
r = 0x00;
}
if (green == false) {
g = 0x00;
}
if (blue == false) {
b = 0x00;
}
BufferedImage tmp = new BufferedImage(
img.getWidth(),
img.getHeight(),
BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < img.getWidth(); i++) {
for (int j = 0; j < img.getHeight(); j++) {
int rgb = img.getRGB(i, j);
int red = (rgb >> 16) & r;
int green = (rgb >> 8) & g;
int blue = (rgb >> 0) & b;
int gbr = (red << 16) | (green << 8) | blue;// EDITED
tmp.setRGB(i, j, gbr);
}
}
img = tmp;
repaint();
} else {
//show error
}
}
感谢您的帮助!
答案 0 :(得分:2)
这个优化版本怎么样,位移很少?
public void channels(boolean showRed, boolean showGreen, boolean showBlue) {
if (this.origImg!= null) {// checks if the image is set
int channelMask = 0xff << 24 | (showRed ? 0xff : 0) << 16 | (showGreen ? 0xff : 0) << 8 | (showBlue ? 0xff : 0);
BufferedImage tmp = new BufferedImage(origImg.getWidth(), origImg.getHeight(), BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < origImg.getWidth(); i++) {
for (int j = 0; j < origImg.getHeight(); j++) {
int rgb = origImg.getRGB(i, j);
tmp.setRGB(i, j, rgb & channelMask);
}
}
img = tmp;
repaint();
} else {
//show error
}
}
更快的方法可能是使用带通道的Raster
或至少Raster
配置允许带子采样(参见Raster.createChild(...)
方法,尤其是最后一个参数)。
LookupOp
也是一个好主意,可能比getRGB()/setRGB()
方法更快。
答案 1 :(得分:1)
看起来你的位错误。不应该是:int gbr = (red << 16) | (green << 8) | blue;
?你基本上想要以与你开始的方式相同的顺序向后移动。
此外,一旦您清除了相应的颜色,就无法将其取回。您需要在某处存储原始图像的副本。如果有时间重新打开频道,只需将原始图像从原始图像复制回来。
假设您将原始图像存储在origImg
某处,我会修改您的for
循环,以便在切换频道时,从原始图像进行复制。
for (int i = 0; i < img.getWidth(); i++) {
for (int j = 0; j < img.getHeight(); j++) {
int rgb = img.getRGB(i, j);
int origRGB = origImg.getRGB(i, j);
int redPixel = red ? (origRGB >> 16) & r : (rgb >> 16) & r;
int greenPixel = green ? (origRGB >> 8) & g : (rgb >> 8) & g;
int bluePixel = blue ? origRGB & b : rgb & b;
int gbr = (redPixel << 16) | (greenPixel << 8) | bluePixel;
tmp.setRGB(i, j, gbr);
}
}