图像滤镜处理功能实现
本文介绍了基于Java的几种图像处理技术,通过操作二维像素数组实现不同效果。主要方法包括:1) drawPixel方法直接绘制像素图像;2) Mosaic方法创建10x10像素块马赛克效果;3) rotate方法实现90度顺时针旋转;4) Grey方法将图像转换为灰度图;5) invert方法生成反色图像。所有方法都通过BufferedImage和Graphics对象处理RGB像素数据,使用位运算
图像处理技术笔记:基于像素数组的操作
本笔记将详细解释提供的Java代码,这些代码实现了多种图像处理功能。代码的核心是操作一个二维像素数组 pixelArr,其中每个元素是一个整数,代表RGB颜色值(如 0xRRGGBB 格式)。通过 BufferedImage 和 Graphics 对象,代码将像素数据渲染成图像。我会逐一解释每个方法,贴出关键代码行,并详细说明其工作原理,确保小白也能理解。
1. drawPixel 方法:绘制像素图像
这个方法将像素数组直接绘制成图像,每个像素对应一个点。
public void drawPixel(int[][] pixelArr) {
BufferedImage bufferedImage = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
Graphics buffG = bufferedImage.getGraphics();
for (int i = 0; i < pixelArr.length; i++) {
for (int j = 0; j < pixelArr[0].length; j++) {
int rgb = pixelArr[i][j];
int red = rgb >> 16 & 0xFF; // 提取红色分量
int green = rgb >> 8 & 0xFF; // 提取绿色分量
int blue = rgb & 0xFF; // 提取蓝色分量
Color color = new Color(red, green, blue); // 创建颜色对象
buffG.setColor(color); // 设置绘图颜色
buffG.drawLine(j, i, j, i); // 绘制单个像素点(起点和终点相同)
}
}
g.drawImage(bufferedImage, 0, 0, pixelsize + bufferedImage.getWidth(), pixelsize + bufferedImage.getHeight(), null);
}
详细解释:
-
创建
BufferedImage对象:BufferedImage bufferedImage = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
这里创建了一个图像对象,宽度是pixelArr[0].length(列数),高度是pixelArr.length(行数),类型为TYPE_INT_RGB,表示使用RGB颜色模型。 -
获取绘图对象:
Graphics buffG = bufferedImage.getGraphics();
通过getGraphics()方法获取一个Graphics对象,用于在图像上绘图。 -
双层循环遍历像素:
for (int i = 0; i < pixelArr.length; i++) { for (int j = 0; j < pixelArr[0].length; j++) { ... } }
外层循环遍历行(i坐标),内层循环遍历列(j坐标),逐个处理每个像素。 -
提取RGB分量:
int red = rgb >> 16 & 0xFF;:右移16位并掩码0xFF提取红色分量(值范围0-255)。int green = rgb >> 8 & 0xFF;:右移8位提取绿色分量。int blue = rgb & 0xFF;:直接掩码提取蓝色分量。
这些操作将整数RGB值分解为三个颜色通道。
-
设置颜色并绘制点:
Color color = new Color(red, green, blue);:用提取的RGB值创建颜色对象。buffG.setColor(color);:设置绘图颜色。buffG.drawLine(j, i, j, i);:绘制一条从(j,i)到(j,i)的线段,实际上只绘制一个点(因为起点和终点相同)。
-
绘制最终图像:
g.drawImage(...);
假设g是上下文中的Graphics对象,用于在屏幕上绘制图像。参数包括图像位置和尺寸,其中pixelsize可能是一个偏移量(如边框大小),null表示无额外观察者。
这个方法将像素数组渲染成原始图像,适合显示或进一步处理。
2. Mosaic 方法:创建马赛克效果
这个方法通过采样像素块来创建马赛克效果,每10x10像素块使用一个颜色。
public void Mosaic(int[][] pixelArr) {
BufferedImage bufferedImage = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
Graphics buffG = bufferedImage.getGraphics();
for (int i = 0; i < pixelArr.length; i += 10) {
for (int j = 0; j < pixelArr[0].length; j += 10) {
int rgb = pixelArr[i][j];
int red = rgb >> 16 & 0xFF; // 提取红色分量
int green = rgb >> 8 & 0xFF; // 提取绿色分量
int blue = rgb & 0xFF; // 提取蓝色分量
Color color = new Color(red, green, blue); // 创建颜色对象
buffG.setColor(color); // 设置绘图颜色
buffG.fillRect(j, i, 10, 10); // 填充10x10矩形区域
}
}
g.drawImage(bufferedImage, 0, 0, pixelsize + bufferedImage.getWidth(), pixelsize + bufferedImage.getHeight(), null);
}
详细解释:
-
创建图像和绘图对象:与
drawPixel类似,创建一个BufferedImage并获取Graphics。 -
跳跃遍历像素:
for (int i = 0; i < pixelArr.length; i += 10) { for (int j = 0; j < pixelArr[0].length; j += 10) { ... } }
循环以步长10遍历行和列,而不是逐像素处理。这意味着只采样每个10x10块的左上角像素。 -
提取颜色和填充矩形:
- 采样当前块左上角像素的RGB值(
pixelArr[i][j]),提取颜色分量。 buffG.fillRect(j, i, 10, 10);:用采样颜色填充一个10x10像素的矩形区域。
这实现了马赛克效果:每个块使用单一颜色,减少细节。
- 采样当前块左上角像素的RGB值(
-
绘制图像:同样使用
g.drawImage输出结果。
马赛克效果通过减少图像分辨率来模糊细节,常用于隐私保护或艺术处理。
3. rotate 方法:旋转像素数组
这个方法将像素数组顺时针旋转90度,返回一个新的数组。
public int[][] rotate(int[][] pixelArr) {
int[][] nArr = new int[pixelArr[0].length][pixelArr.length]; // 新数组,行列互换
for (int i = 0; i < pixelArr.length; i++) {
for (int j = 0; j < pixelArr[0].length; j++) {
nArr[j][pixelArr.length - i - 1] = pixelArr[i][j]; // 索引映射实现旋转
}
}
return nArr;
}
详细解释:
-
创建新数组:
int[][] nArr = new int[pixelArr[0].length][pixelArr.length];
新数组的宽度是原数组的高度(pixelArr.length),高度是原数组的宽度(pixelArr[0].length),实现行列互换。 -
双层循环遍历原数组:
for (int i = 0; i < pixelArr.length; i++) { for (int j = 0; j < pixelArr[0].length; j++) { ... } }
遍历原数组的每个像素。 -
索引映射实现旋转:
nArr[j][pixelArr.length - i - 1] = pixelArr[i][j];- 原数组的像素
(i,j)映射到新数组的(j, pixelArr.length - i - 1)。 - 例如,原数组左上角
(0,0)会映射到新数组右上角(0, pixelArr.length - 1)。 pixelArr.length - i - 1确保行索引从下到上翻转,实现90度顺时针旋转。
- 原数组的像素
-
返回新数组:
return nArr;
返回旋转后的像素数组,可以直接用于其他方法(如drawPixel)。
这个方法不直接绘制图像,而是处理像素数据,适合在显示前调整图像方向。
4. Grey 方法:转换为灰度图像
这个方法将彩色图像转换为灰度图像,通过计算每个像素的灰度值。
public void Grey(int[][] pixelArr) {
BufferedImage bufferedImage = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
Graphics buffG = bufferedImage.getGraphics();
for (int i = 0; i < pixelArr.length; i += 1) {
for (int j = 0; j < pixelArr[0].length; j += 1) {
int rgb = pixelArr[i][j];
int red = rgb >> 16 & 0xFF; // 提取红色分量
int green = rgb >> 8 & 0xFF; // 提取绿色分量
int blue = rgb & 0xFF; // 提取蓝色分量
int grey = (red + green + blue) / 3; // 计算灰度值
Color color = new Color(grey, grey, grey); // 灰度颜色(RGB相同)
buffG.setColor(color); // 设置绘图颜色
buffG.fillRect(j, i, 1, 1); // 填充单个像素
}
}
g.drawImage(bufferedImage, 0, 0, pixelsize + bufferedImage.getWidth(), pixelsize + bufferedImage.getHeight(), null);
}
详细解释:
-
创建图像和绘图对象:与之前方法相同。
-
逐像素遍历:
for (int i = 0; i < pixelArr.length; i += 1) { for (int j = 0; j < pixelArr[0].length; j += 1) { ... } }
步长为1,处理每个像素。 -
计算灰度值:
int grey = (red + green + blue) / 3;
将RGB三个分量求平均值,得到灰度值(0-255),代表亮度。这是一种简单的灰度化方法。 -
设置灰度颜色:
Color color = new Color(grey, grey, grey);
用相同的灰度值设置RGB,创建灰色调。 -
填充像素:
buffG.fillRect(j, i, 1, 1);
用灰度颜色填充一个1x1像素的矩形,相当于绘制一个点。 -
绘制图像:输出灰度图像。
灰度化常用于简化图像处理或创建黑白效果。
5. invert 方法:反色图像
这个方法将图像颜色反转,创建负片效果。
public void invert(int[][] pixelArr) {
BufferedImage bufferedImage = new BufferedImage(pixelArr[0].length, pixelArr.length, BufferedImage.TYPE_INT_RGB);
Graphics buffG = bufferedImage.getGraphics();
for (int i = 0; i < pixelArr.length; i += 1) {
for (int j = 0; j < pixelArr[0].length; j += 1) {
int rgb = pixelArr[i][j];
int red = rgb >> 16 & 0xFF; // 提取红色分量
int green = rgb >> 8 & 0xFF; // 提取绿色分量
int blue = rgb & 0xFF; // 提取蓝色分量
Color color = new Color(255 - red, 255 - green, 255 - blue); // 反色计算
buffG.setColor(color); // 设置绘图颜色
buffG.fillRect(j, i, 1, 1); // 填充单个像素
}
}
g.drawImage(bufferedImage, 0, 0, pixelsize + bufferedImage.getWidth(), pixelsize + bufferedImage.getHeight(), null);
}
详细解释:
-
创建图像和绘图对象:标准步骤。
-
逐像素遍历:处理每个像素。
-
反色计算:
Color color = new Color(255 - red, 255 - green, 255 - blue);
对每个RGB分量取反:用255减去原值。例如,红色255变为0(黑色),红色0变为255(红色)。这实现颜色反转。 -
填充像素:
buffG.fillRect(j, i, 1, 1);绘制反色点。 -
绘制图像:输出反色图像。
反色效果常用于艺术处理或增强对比度。
总结
这些代码展示了基本的图像处理技术,使用Java的 BufferedImage 和 Graphics 类操作像素数组。关键点包括:
- 像素数组结构:二维数组
int[][] pixelArr,行索引i对应Y坐标,列索引j对应X坐标。 - RGB处理:通过位操作提取和设置颜色分量。
- 绘图方法:使用
drawLine或fillRect绘制点或块。 - 通用输出:
g.drawImage负责最终显示,假设g和pixelsize在上下文中定义。
通过这些方法,小白可以学习如何实现图像绘制、马赛克、旋转、灰度化和反色等常见效果。代码结构清晰,易于扩展,但需注意性能优化(如循环效率)和边界处理。
更多推荐

所有评论(0)