我将图像存储为像素值的二维数组。我想更改图像的对比度和亮度,然后将更改的像素图像存储为图像,然后在JFrame中显示原始图像和更改的图像。所以我的问题的基本步骤是:
我可以做第4步没问题,我想我也正在做第1步。然而,我无法工作的是第2步和第3步。我尝试过不同的方法,但总是会出现非常扭曲的图像。只是将图像转换为像素阵列然后再次返回图像(不改变像素值)会在不应该的情况下产生非常扭曲的图像。请看下面的图片。
这是一个学校作业,所以我们必须自己实现这个功能(改变对比度和亮度),否则我会使用一些类似question建议的内置函数。
任何可以提供帮助的人?在此先感谢您的帮助!
我的代码
我已将每一步(第4步除外)放在一个单独的方法中,以便更容易阅读和理解。
图片 - >二维像素阵列
/**
* converts an image to a 2 dimensional pixel-array
*/
public static int[][] imageToPixelArray() throws IOException {
File file = new File(filename);
imageOriginal = ImageIO.read(file);
Raster raster = imageOriginal.getData();
int width = raster.getWidth();
int height = raster.getHeight();
pixels = new int[width][height];
sampleModel = raster.getSampleModel();
int color = 3;
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
for(int c = 0; c < color; c++) {
pixels[i][j] = raster.getSample(i, j, c);
}
}
}
return pixels;
}
更改像素值
public static int[][] compute(int[][] pixels) {
contrast = 20;
brightness = 20;
for(int i = 0; i < pixels.length; i++) {
for(int j = 0; j < pixels[i].length; j++) {
pixels[i][j] = pixels[i][j] * contrast + brightness;
}
}
return pixels;
}
2维pixelarray - &gt;图片
/**
* converts a 2 dimensional pixel-array to an image
*/
public static BufferedImage pixelArrayToImage(int[][] pixels) {
int width = pixels.length;
int height = pixels[0].length;
WritableRaster raster = Raster.createWritableRaster(sampleModel, new Point(0, 0));
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
raster.setSample(i, j, 0, pixels[i][j]);
}
}
imageAltered = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
imageAltered.setData(raster);
return imageAltered;
}
答案 0 :(得分:1)
您的整个代码没有意义。我不会谈论语法,因为我的Java非常生疏,我不会给你一个解决方案,因为这会损害你的学习经验。但我会指出一些事情。
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
for(int c = 0; c < color; c++) {
pixels[i][j] = raster.getSample(i, j, c);
}
}
}
为什么要将一行中的三个不同值分配给同一个整数pixels[i][j]
?您可以使用另一个数组来存储每个像素的三个值,也可以找到一些其他方法来编码rgb信息。
public static int[][] compute(int[][] pixels) {
contrast = 20;
brightness = 20;
for(int i = 0; i < pixels.length; i++) {
for(int j = 0; j < pixels[i].length; j++) {
pixels[i][j] = pixels[i][j] * contrast + brightness;
}
}
return pixels;
}
你是如何提出pixels[i][j] = pixels[i][j] * contrast + brightness;
的?
这不会改变对比度,只需使图像更亮。对比不是全球因素。我认为您需要掌握一些关于数字图像,结构和值以及最少图像处理术语的基本知识。
如果您将rgb图像缩小为单个频道,则会丢弃无法获取的信息。不幸的是,你并没有真正描述你想要达到的目标,所以我不能给你很多建议。但是你的代码是无稽之谈。
答案 1 :(得分:0)
我设法解决了我的问题(并在此过程中缩短了我的代码)!我的代码通过生成由间隔给出的随机值来改变亮度和对比度。
如果其他人遇到同样的问题,这是代码:)
/**
* alter the image´s contrast and brightness
* @throws IOException
*/
public void alterImage() throws IOException {
imageAltered = new BufferedImage(imageOriginal.getWidth(), imageOriginal.getHeight(), BufferedImage.TYPE_INT_RGB);
brightness = rand.nextInt(150 + 200 + 1) - 200; //values from 150 to 200
contrast = 1.5 + (5.0 - 1.5) * rand.nextDouble(); //values from 1.5 to 5.0
for(int i = 0; i < imageOriginal.getWidth(); i++) {
for(int j = 0; j < imageOriginal.getHeight(); j++) {
Color c = new Color(imageOriginal.getRGB(i, j));
int red = (int) contrast * c.getRed() + brightness;
int green = (int) contrast * c.getGreen() + brightness;
int blue = (int) contrast * c.getBlue() + brightness;
if(red > 255) { // the values of the color components must be between 0-255
red = 255;
} else if(red < 0) {
red = 0;
}
if(green > 255) {
green = 255;
} else if(green < 0) {
green = 0;
}
if(blue > 255) {
blue = 255;
} else if(blue < 0) {
blue = 0;
}
imageAltered.setRGB(i, j, new Color(red, green, blue).getRGB());
}
}
}