本文目录导读:

BufferedImage 是 Java 中处理图像的核心类,位于 java.awt.image 包下,它允许你在内存中创建一个可操作的图像缓冲区,并进行读取、绘制、像素操作和保存。
以下是 BufferedImage 最常用、最核心的操作指南。
创建 BufferedImage
通常有三种方式创建:
import java.awt.image.BufferedImage;
import java.awt.Color;
import java.awt.Graphics2D;
// 方法1:直接创建一个空白的 RGB 图像
int width = 200;
int height = 200;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 方法2:创建带透明度的 ARGB 图像
BufferedImage transparentImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// 方法3:从文件读取图像
// import javax.imageio.ImageIO;
// import java.io.File;
// BufferedImage loadedImage = ImageIO.read(new File("path/to/image.png"));
常见图像类型(imageType):
TYPE_INT_RGB:不透明,标准 RGB(红绿蓝)TYPE_INT_ARGB:带 Alpha 通道(透明度)TYPE_3BYTE_BGR:字节顺序为 BGR,常见于 Windows 图片
在图像上绘制(使用 Graphics2D)
这是最常用的方式——在图像上画线、文字、几何图形或贴图。
// 获取 Graphics2D 画笔(强烈推荐转型,功能更强)
Graphics2D g2d = image.createGraphics();
// --- 背景填充 ---
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height); // 用白色填充整个画布
// --- 设置绘画属性 ---
g2d.setColor(Color.BLUE); // 设置画笔颜色
g2d.drawRect(10, 10, 100, 50); // 画矩形框
g2d.fillRect(50, 50, 80, 80); // 画实心矩形
// --- 画线 ---
g2d.setColor(Color.RED);
g2d.drawLine(0, 0, 200, 200); // 画一条对角线
// --- 画圆/椭圆 ---
g2d.setColor(Color.GREEN);
g2d.drawOval(20, 20, 100, 100); // 画圆框
g2d.fillOval(30, 30, 80, 80); // 画实心圆
// --- 画文字 ---
g2d.setColor(Color.BLACK);
g2d.setFont(new Font("Serif", Font.BOLD, 24));
g2d.drawString("Hello Java", 50, 150); // 在坐标(50,150)画文字
// --- 贴上另一张图(渲染另一个 BufferedImage) ---
BufferedImage logo = ImageIO.read(new File("logo.png"));
g2d.drawImage(logo, 10, 10, null); // 在(10,10)处贴图
// --- 释放资源(非常重要!)---
g2d.dispose();
⚠️ 每次使用
createGraphics()后,必须调用g2d.dispose()释放系统资源。
直接操作像素(获取/设置颜色)
如果你想逐像素修改图像(比如滤镜、颜色变换),可以直接访问像素数组。
getRGB / setRGB(简单但较慢,适合小区域)
// 获取某个像素的 ARGB 值
int x = 10, y = 20;
int argb = image.getRGB(x, y);
// 解析 ARGB(可选)
int alpha = (argb >> 24) & 0xFF;
int red = (argb >> 16) & 0xFF;
int green = (argb >> 8) & 0xFF;
int blue = argb & 0xFF;
// 创建一个新颜色并设置
Color color = new Color(255, 0, 0); // 红色,不透明
image.setRGB(x, y, color.getRGB()); // 设置像素
// 批量修改整块区域(性能好很多)
int[] pixels = image.getRGB(0, 0, width, height, null, 0, width);
for (int i = 0; i < pixels.length; i++) {
// 示例:将红色通道设为最大值
int rgb = pixels[i];
int alpha = (rgb >> 24) & 0xFF;
int red = 255; // 设为最红
int green = (rgb >> 8) & 0xFF;
int blue = rgb & 0xFF;
pixels[i] = (alpha << 24) | (red << 16) | (green << 8) | blue;
}
image.setRGB(0, 0, width, height, pixels, 0, width);
使用 Raster 和 DataBuffer(高性能,适合视频帧/实时处理)
// 获取像素数据数组(直接操作内存)
int[] data = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
for (int i = 0; i < data.length; i++) {
// 直接修改 data[i] 的 ARGB 值
}
// 注意:这种方法需要图像类型是 TYPE_INT_RGB 或 TYPE_INT_ARGB
// 且修改后图像自动更新,无需 setRGB
调整图像尺寸(缩放)
import java.awt.image.BufferedImage;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
public static BufferedImage resize(BufferedImage original, int newWidth, int newHeight) {
BufferedImage resized = new BufferedImage(newWidth, newHeight, original.getType());
Graphics2D g2d = resized.createGraphics();
// 启用抗锯齿,提高缩放质量
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.drawImage(original, 0, 0, newWidth, newHeight, null);
g2d.dispose();
return resized;
}
保存 BufferedImage 到文件
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
try {
// 保存为 PNG(无损,支持透明)
ImageIO.write(image, "png", new File("output.png"));
// 保存为 JPG(有损,不支持透明,背景会变黑)
// ImageIO.write(image, "jpg", new File("output.jpg"));
System.out.println("图片保存成功!");
} catch (IOException e) {
e.printStackTrace();
}
⚠️ 如果图片带透明通道(ARGB),不要存成 JPG,否则透明部分会变黑色,存为 PNG 最安全。
常见陷阱与最佳实践
| 问题 | 解决方案 |
|---|---|
忘记调用 dispose() |
每次 createGraphics() 后 finally 或 try-with-resources 释放 |
| 透明背景变成黑色 | 使用 TYPE_INT_ARGB 创建,保存为 PNG |
| 坐标越界 | 始终检查 x>=0 && x<width && y>=0 && y<height |
| 性能慢(逐像素改) | 用 getRGB(..., pixelArray) 批量访问 |
| 图像类型不匹配 | 读取图片后可用 new BufferedImage(w, h, TYPE_INT_ARGB) 创建新画布再绘制 |
推荐模板:高效处理像素(颜色反转示例)
BufferedImage img = ImageIO.read(new File("input.jpg"));
int w = img.getWidth();
int h = img.getHeight();
// 确保类型是 INT_RGB 或 INT_ARGB
BufferedImage result = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = result.createGraphics();
g.drawImage(img, 0, 0, null);
g.dispose();
int[] pixels = result.getRGB(0, 0, w, h, null, 0, w);
for (int i = 0; i < pixels.length; i++) {
int argb = pixels[i];
int a = (argb >> 24) & 0xFF;
int r = 255 - ((argb >> 16) & 0xFF);
int g = 255 - ((argb >> 8) & 0xFF);
int b = 255 - (argb & 0xFF);
pixels[i] = (a << 24) | (r << 16) | (g << 8) | b;
}
result.setRGB(0, 0, w, h, pixels, 0, w);
ImageIO.write(result, "jpg", new File("inverted.jpg"));
掌握这些操作,你就能用 BufferedImage 完成大部分图像处理任务了,如果还有其他具体需求(如裁剪、滤镜、旋转),可以继续提问。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播