ImageIO.read(url)读取图片,返回null

URL url1 = new URL(url);
BufferedImage read = ImageIO.read(url1);读取图片,返回null。
已经知道使用浏览器可以正常打开url.

1. ImageIO 支持的图片格式
JavaImageIO 默认支持以下格式:

JPEG
PNG
GIF
BMP
WBMPWireless Bitmap)

对于其他格式(如 WebPHEIC 等),需添加第三方库(如 imageio-webp)才能支持。
检查当前环境支持的格式:(通过文件头签名直接判断格式)
原理:每种图片格式都有特定的二进制文件头(Magic Number),直接读取文件前几个字节即可判断格式。
优点:最可靠,不受环境依赖限制。
String[] formats = ImageIO.getReaderFormatNames();
System.out.println("支持的格式:" + Arrays.toString(formats));

获取图片的格式:
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Map;

public class ImageFormatDetector {

    // 常见图片格式的文件头签名(十六进制)
    private static final Map<String, String> FILE_SIGNATURES = new HashMap<>();
    static {
        FILE_SIGNATURES.put("FFD8FF", "jpg");    // JPEG/JFIF
        FILE_SIGNATURES.put("89504E47", "png");   // PNG
        FILE_SIGNATURES.put("47494638", "gif");   // GIF
        FILE_SIGNATURES.put("424D", "bmp");       // BMP
        FILE_SIGNATURES.put("52494646", "webp");  // WebP (RIFF header)
        FILE_SIGNATURES.put("49492A00", "tif");  // TIFF (little-endian)
        FILE_SIGNATURES.put("4D4D002A", "tif");  // TIFF (big-endian)
    }

    public static String detectFormat(String filePath) throws IOException {
        try (RandomAccessFile raf = new RandomAccessFile(filePath, "r")) {
            byte[] header = new byte[4];
            raf.read(header);
            String hexHeader = bytesToHex(header).toUpperCase();

            // 匹配最长可能的签名(例如 WebP 需要至少 4 字节)
            for (Map.Entry<String, String> entry : FILE_SIGNATURES.entrySet()) {
                String signature = entry.getKey();
                if (hexHeader.startsWith(signature)) {
                    return entry.getValue();
                }
            }
            return "unknown";
        }
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X", b & 0xFF));
        }
        return sb.toString();
    }

    public static void main(String[] args) throws IOException {
        String format = detectFormat("image.webp");
        System.out.println("图片格式:" + format); // 输出 webp
    }
}

可能的原因及解决方案
原因 1:图片格式不支持
示例:尝试读取 WebP 格式但未添加插件。

解决方案:
添加对应依赖:

<!-- 例如 WebP 支持 -->
<dependency>
  <groupId>com.github.hoary</groupId>
  <artifactId>javav-webp-imageio</artifactId>
  <version>1.0.2</version>
</dependency>

2. 验证 WebP 支持
添加依赖后,检查 ImageIO 是否已识别 WebP 格式:
import javax.imageio.ImageIO;

public class WebPTest {
    public static void main(String[] args) {
        // 列出所有支持的格式
        String[] formats = ImageIO.getReaderFormatNames();
        System.out.println("支持的图片格式:" + Arrays.toString(formats));
        // 输出应包含 "webp"
    }
}
3. 读取 WebP 图片 
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.net.URL;

public class ReadWebP {
    public static void main(String[] args) {
        try {
            URL url = new URL("你的图片URL");
            BufferedImage image = ImageIO.read(url);
            
            if (image != null) {
                System.out.println("成功读取 WebP 图片,尺寸:" + image.getWidth() + "x" + image.getHeight());
            } else {
                System.err.println("ImageIO 无法解码该图片(可能数据损坏或格式不兼容)");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

原因 2:服务器拒绝 Java 请求
某些服务器会拦截非浏览器 User-Agent 的请求。

解决方案:设置 HTTP 请求头:

HttpURLConnection conn = (HttpURLConnection) url1.openConnection();
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
BufferedImage image = ImageIO.read(conn.getInputStream());

原因 3:输入流读取失败
网络问题或 URL 重定向可能导致数据无法正确读取。

验证数据是否下载成功:

try (InputStream in = url1.openStream()) {
  byte[] data = in.readAllBytes();
  System.out.println("读取字节数:" + data.length); // 如果为0,说明数据未下载
}