Raster (像素數據) + ColorModel (色彩空間解釋)
// 讀取
File input = new File("input.jpg");
BufferedImage image = ImageIO.read(input); // 返回 null 表示格式不支援或損壞
// 寫入
File output = new File("output.png");
boolean success = ImageIO.write(image, "png", output); // 格式名區分大小寫
if (!success) throw new IllegalStateException("無對應 ImageWriter");
int type = image.getType();
int w = image.getWidth(), h = image.getHeight();
int[] pixels = new int[w * h];
if (type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB) {
// 直接從 Raster 獲取數組引用 (零拷貝)
image.getRaster().getDataElements(0, 0, w, h, pixels);
} else {
// 其他類型需轉換為 INT_ARGB 內部表示
image.getRGB(0, 0, w, h, pixels, 0, w);
}
if (type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB) {
image.getRaster().setDataElements(0, 0, w, h, pixels);
} else {
image.setRGB(0, 0, w, h, pixels, 0, w);
}
// 解包:0xAARRGGBB -> 四分量
int alpha = (argb >> 24) & 0xFF;
int red = (argb >> 16) & 0xFF;
int green = (argb >> 8) & 0xFF;
int blue = argb & 0xFF;
// 打包:四分量 -> 0xAARRGGBB
int argb = (alpha << 24) | (red << 16) | (green << 8) | blue;
// 快捷方法 (Color 類)
Color c = new Color(argb, true); // true=hasAlpha
int r = c.getRed();
int argb2 = c.getRGB();
// Swing 環境下異步加載大圖
MediaTracker tracker = new MediaTracker(component); // component 為 Component 實例
tracker.addImage(image, 0); // ID=0
new Thread(() -> {
try { tracker.waitForID(0, 10000); } // 等待 10 秒
catch (InterruptedException e) { /* 超時或中斷 */ }
if (tracker.isErrorID(0)) { /* 加載失敗 */ }
else { /* 加載成功,可安全繪製 */ }
}).start();
public class PlasmaGenerator extends JComponent {
private static final int SIZE = 256;
private BufferedImage cachedImage;
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawImage(getPlasmaImage(), 10, 10, null);
}
private BufferedImage getPlasmaImage() {
if (cachedImage != null) return cachedImage;
cachedImage = new BufferedImage(SIZE, SIZE, BufferedImage.TYPE_INT_ARGB);
int[] rgbData = new int[SIZE * SIZE];
generatePlasma(rgbData);
setRGB(cachedImage, 0, 0, SIZE, SIZE, rgbData);
// 順便保存文件
try { ImageIO.write(cachedImage, "jpg", new File("plasma.jpg")); }
catch (IOException e) { e.printStackTrace(); }
return cachedImage;
}
private void generatePlasma(int[] rgbData) {
for (int y = 0; y < SIZE; y++) {
for (int x = 0; x < SIZE; x++) {
// 正弦波干涉產生等離子體效果
double v = Math.sin((x + y) / 8.0) * 128 + 128;
int c = clamp((int) v);
int idx = y * SIZE + x;
rgbData[idx] = (0xFF << 24) | (c << 16) | (c << 8) | c; // 灰階
}
}
}
private int clamp(int v) { return Math.max(0, Math.min(255, v)); }
private void setRGB(BufferedImage img, int x, int y, int w, int h, int[] pixels) {
int type = img.getType();
if (type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB) {
img.getRaster().setDataElements(x, y, w, h, pixels);
} else {
img.setRGB(x, y, w, h, pixels, 0, w);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame f = new JFrame("Plasma Noise");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new PlasmaGenerator());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
twelvemonkeys-imageio)ImageReader/WriterSpi 打包為 JAR-Xbootclasspath/a:plugins.jar (Java 8) / 模組化服務發現 (Java 9+)掌握 BufferedImage + ImageIO + Raster 三位一體,配合 getDataElements/setDataElements 批量像素操作,是 Java 圖像處理的性能基石。對於生產級圖像管道,建議引入 TwelveMonkeys ImageIO 擴展格式支援,並考慮 Java Advanced Imaging (JAI) 或 OpenCV Java Bindings 處理複雜算法。