我正试图解决读取图像的问题。我需要排除像素中的蓝色通道,以便产生RG图像。对阵列中的像素数据进行平均处理
这是我到目前为止没有工作的D;
我需要创建一个新的BufferedImage并将每个平均像素(没有蓝色通道)应用于它吗?我不知道该怎么做。
我正试图解决读取图像的问题。我需要排除像素中的蓝色通道,以便产生RG图像。对阵列中的像素数据进行平均处理
这是我到目前为止没有工作的D;
我需要创建一个新的BufferedImage并将每个平均像素(没有蓝色通道)应用于它吗?我不知道该怎么做。
对于初学者来说,你的代码第二到最后一行改变这一点,看看是否有帮助:
image.setRGB(i, j, (redData[i][j] << 16) | (greenData[i][j] << 8));
但有了这个,你将结束,其大小一样的图像原来,除了你放弃了蓝色通道,并且你在其他通道上的平均值(类似于模糊),但只在每个2×2块的左上角。
如果你想真正创建的四分之一大小的图像,你确实需要创建一个新的BufferedImage
与宽度和高度的一半,然后将上述行更改为:
newImage.setRGB(i/2, j/2, (redData[i][j] << 16) | (greenData[i][j] << 8));
这里是一个你的代码的更新版本应该这样做(未经测试):
public static BufferedImage isolateBlueChannelAndResize(BufferedImage image) {
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
// Round down for odd-sized images to prevent indexing outside image
if ((imageWidth & 1) > 0) imageWidth --;
if ((imageHeight & 1) > 0) imageHeight--;
BufferedImage newImage = new BufferedImage(imageWidth/2, imageHeight/2, image.getType());
for (int i = 0; i < imageWidth; i += 2) {
for (int j = 0; j < imageHeight; j += 2) {
int r1 = (image.getRGB(i , j ) >> 16) & 0xff;
int r2 = (image.getRGB(i+1, j ) >> 16) & 0xff;
int r3 = (image.getRGB(i , j+1) >> 16) & 0xff;
int r4 = (image.getRGB(i+1, j+1) >> 16) & 0xff;
int red = (r1 + r2 + r3 + r4 + 3)/4; // +3 rounds up (equivalent to ceil())
int g1 = (image.getRGB(i , j ) >> 8) & 0xff;
int g2 = (image.getRGB(i+1, j ) >> 8) & 0xff;
int g3 = (image.getRGB(i , j+1) >> 8) & 0xff;
int g4 = (image.getRGB(i+1, j+1) >> 8) & 0xff;
int green = (g1 + g2 + g3 + g4 + 3)/4; // +3 rounds up (equivalent to ceil())
newImage.setRGB(i/2, j/2, (red << 16) | (green << 8));
}
}
return newImage;
}
感谢让我尝试实现它; D – user3526114
我创建了一个新的图像使用: 'BufferedImage newImage = new BufferedImage(imageWidth/2,imageHeight/2,image.getType());' 并使用您的以上设置像素line: 'newImage.setRGB(i/2,j/2,(redData [i] [j] << 16)|(greenData [i] [j] << 8));'但是它输出原始图像,相同的大小和一切都没有预期的黄色色调 – user3526114
你是否改变了说'return image;'到'return newImage;'的行? ;) –
我真的觉得更简单的方法是使用Color
类:
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class AverageOutBlue {
public static final float AVG_FACTOR = 1f/(4f * 255f);
public static BufferedImage processImage(final BufferedImage src) {
final int w = src.getWidth();
final int h = src.getHeight();
final BufferedImage out = new BufferedImage(w/2, h/2, src.getType());
for (int i = 0; i < w; i += 2)
for (int j = 0; j < h; j += 2) {
final Color color = avgColor(src, i, j);
out.setRGB(i/2, j/2, color.getRGB());
}
return out;
}
private static Color avgColor(final BufferedImage src, final int i,
final int j) {
final Color c1 = new Color(src.getRGB(i, j));
final Color c2 = new Color(src.getRGB(i + 1, j));
final Color c3 = new Color(src.getRGB(i + 1, j));
final Color c4 = new Color(src.getRGB(i + 1, j + 1));
final float r = (c1.getRed() + c2.getRed() + c3.getRed() + c4.getRed())
* AVG_FACTOR;
final float g = (c1.getGreen() + c2.getGreen() + c3.getGreen() +
c4.getGreen()) * AVG_FACTOR;
return new Color(r, g, 0f);
}
}
如果您不想使用Color类,那么您可以像上面尝试的那样对具有“int”RGB值的像素求平均值(使用移位和蒙版),然后返回一个整数而不是“Color”目的。 – Jared
因此,您需要拍摄2mX2n像素的图像并将其转换为mXn图像,并且每个像素(最终)都是原始像素的平均像素数减去蓝色成分(即,蓝色部分将始终为零)? – Jared
是的,基本上就是这样!但我似乎无法弄清楚如何去做。 :S – user3526114
评论:平均RGB值会使图像质量稍微恶化。 RGB值与亮度没有线性关系(已应用伽马曲线)。结果比应该更暗。但是做正确的事情涉及到很慢。看看你是否感兴趣:http://www.4p8.com/eric.brasseur/gamma.html –