- 图片转字节数组,带有格式的(即包含头部格式部分)
public static byte[] imageToByteArray(BufferedImage image, String format) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 将图像以指定格式(如 "png", "jpg")写入字节流 ImageIO.write(image, format, baos); // 从流中获取完整的字节数组 return baos.toByteArray(); }
- 字节数组转图片,带有格式的
public static BufferedImage byteArrayToImage(byte[] imageBytes) throws IOException { // 将字节数组包装为输入流 ByteArrayInputStream bais = new ByteArrayInputStream(imageBytes); // 读取并解码为 BufferedImage return ImageIO.read(bais); }
- 获取具体的每个像素值,明了但低效的方式
public int[][] getPixelArraySlow(BufferedImage image) { int width = image.getWidth(); int height = image.getHeight(); int[][] result = new int[height][width]; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { // 获取每个像素的ARGB值,组合成一个int result[row][col] = image.getRGB(col, row); } } return result; }
直接从DataBuffer获取(高效)
对于性能敏感的应用,直接读取图像的数据缓冲区是更好的选择。需要注意区分图像是否包含Alpha通道
public int[][] getPixelArrayFast(BufferedImage image) { // 直接从Raster获取底层字节数据 byte[] pixelData = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); int width = image.getWidth(); int height = image.getHeight(); boolean hasAlphaChannel = image.getAlphaRaster() != null; int[][] result = new int[height][width]; int pixelIndex = 0; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { int argb = 0; if (hasAlphaChannel) { // 数据顺序通常为: 蓝, 绿, 红, 阿尔法 argb = (((int) pixelData[pixelIndex + 3] & 0xff) << 24) | // Alpha (((int) pixelData[pixelIndex + 2] & 0xff) << 16) | // Red (((int) pixelData[pixelIndex + 1] & 0xff) << 8) | // Green ((int) pixelData[pixelIndex] & 0xff); // Blue pixelIndex += 4; } else { // 无Alpha通道,数据顺序为: 蓝, 绿, 红 argb = (0xff << 24) | // 完全不透明 (((int) pixelData[pixelIndex + 2] & 0xff) << 16) | // Red (((int) pixelData[pixelIndex + 1] & 0xff) << 8) | // Green ((int) pixelData[pixelIndex] & 0xff); // Blue pixelIndex += 3; } result[row][col] = argb; } } return result; }从像素数组创建BufferedImage
这是逆向过程,最常用setRGB()方法,它接受一个一维数组
public BufferedImage createImageFromArray(int[] pixels, int width, int height) { // 创建一个指定尺寸和类型的RGB图像 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 将像素数组一次性设置到图像中 image.setRGB(0, 0, width, height, pixels, 0, width); return image; }