java 判断图片格式
【代码】java 判断图片格式。
·
public static String getImageFormatName_v1( File imageFile ) {
try (ImageInputStream imageInputStream = ImageIO.createImageInputStream(imageFile)) {
Iterator<ImageReader> imageReadersList = ImageIO.getImageReaders(imageInputStream);
if (!imageReadersList.hasNext()) {
log.error("Cannot detect image format by ImageIO.getImageReaders" );
return ImageUtils.getImageFormatByHeader( imageFile );
}
return imageReadersList.next().getFormatName();
} catch (IOException e) {
log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e );
throw new BusinessLogicException( "失败" );
}
}
public static String getImageFormatByHeader(File imageFile) {
// 读取文件前12字节(覆盖所有格式的头部长度)
byte[] header = new byte[12];
try (FileInputStream fis = new FileInputStream(imageFile)) {
int bytesRead = fis.read(header);
if (bytesRead < 12) { // 处理小文件场景
header = Arrays.copyOf(header, bytesRead);
}
} catch (Exception e) {
log.error(CommonConstans.EXCEPTION_LOG_PREFIX, e);
return null;
}
// 按格式特征优先级检测(特征越独特越靠前)
if (isWebP(header)) {
return "WEBP";
} else if (isPNG(header)) {
return "PNG";
} else if (isGIF(header)) {
return "GIF";
} else if (isTIFF(header)) {
return "TIFF";
} else if (isBMP(header)) {
return "BMP";
} else if (isJPEG(header)) {
return "JPEG";
}
return null;
}
//--- 各格式检测逻辑 ---//
private static boolean isJPEG(byte[] header) {
return header.length >= 2
&& (header[0] & 0xFF) == 0xFF
&& (header[1] & 0xFF) == 0xD8;
}
private static boolean isPNG(byte[] header) {
return header.length >= 8
&& header[0] == (byte) 0x89
&& header[1] == 0x50 // P
&& header[2] == 0x4E // N
&& header[3] == 0x47 // G
&& header[4] == 0x0D
&& header[5] == 0x0A
&& header[6] == 0x1A
&& header[7] == 0x0A;
}
private static boolean isGIF(byte[] header) {
if (header.length < 6) return false;
String headerStr = new String(header, 0, 6, StandardCharsets.US_ASCII);
return "GIF87a".equals(headerStr) || "GIF89a".equals(headerStr);
}
private static boolean isBMP(byte[] header) {
return header.length >= 2
&& header[0] == 0x42 // B
&& header[1] == 0x4D; // M
}
private static boolean isWebP(byte[] header) {
return header.length >= 12
&& header[0] == 0x52 // R
&& header[1] == 0x49 // I
&& header[2] == 0x46 // F
&& header[3] == 0x46 // F
&& header[8] == 0x57 // W
&& header[9] == 0x45 // E
&& header[10] == 0x42 // B
&& header[11] == 0x50; // P
}
private static boolean isTIFF(byte[] header) {
return header.length >= 4
&& ((header[0] == 0x49 && header[1] == 0x49 && header[2] == 0x2A && header[3] == 0x00) // II*格式
|| (header[0] == 0x4D && header[1] == 0x4D && header[2] == 0x00 && header[3] == 0x2A)); // MM*格式
}
public static String getImageFormatName_v2( String imageUrl ) {
ImageInputStream iis = null;
try{
URL url = new URL(imageUrl);
iis = ImageIO.createImageInputStream( url.openStream() );
Iterator<ImageReader> imageReadersList = ImageIO.getImageReaders(iis);
if (!imageReadersList.hasNext()) {
log.error("Cannot detect image format by ImageIO.getImageReaders" );
return ImageUtils.getImageFormatByHeader( imageUrl );
}
return imageReadersList.next().getFormatName();
} catch (IOException e) {
log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e );
throw new BusinessLogicException( "失败" );
}finally {
MyFileUtils.closeCloseable( iis );
}
}
public static String getImageFormatByHeader(String imageUrl) {
// 1. 验证URL有效性
if (imageUrl == null || imageUrl.isEmpty()) {
log.error("Invalid image URL");
return null;
}
// 2. 创建HTTP连接
try (InputStream urlStream = new URL(imageUrl).openStream();
BufferedInputStream bufferedStream = new BufferedInputStream(urlStream)) {
// 3. 读取前12字节(文件头)
byte[] header = new byte[12];
int bytesRead = bufferedStream.read(header, 0, 12);
if (bytesRead < 12) {
header = Arrays.copyOf(header, bytesRead);
}
// 4. 格式检测逻辑(与原方法一致)
if (isWebP(header)) {
return "WEBP";
} else if (isPNG(header)) {
return "PNG";
} else if (isGIF(header)) {
return "GIF";
} else if (isTIFF(header)) {
return "TIFF";
} else if (isBMP(header)) {
return "BMP";
} else if (isJPEG(header)) {
return "JPEG";
}
} catch (MalformedURLException e) {
log.error("Malformed URL: {}", imageUrl);
} catch (IOException e) {
log.error("Failed to read from URL: {}", imageUrl);
}
return null;
}
/**
* 多次调用该方法获取 multipartFile 表示图片的图片格式不会影响后续对 multipartFile 的使用,
* 因为 Spring 的 MultipartFile 实现(如 StandardMultipartFile)默认基于临时文件存储上传内容,这使得:
* 每次调用 getInputStream() 会返回一个新的 InputStream,从头开始读取文件。
* 流的独立性:每个 InputStream 实例独立读取文件,互不影响。
* 每次 getInputStream():生成新的文件输入流,读取前 12 字节后关闭流。
* 不影响后续操作:所有读取操作均基于独立的流,文件指针始终从头开始。
* @param imageFile
* @return
*/
public static String getImageFormatName_v3(MultipartFile imageFile) {
try (InputStream fileStream = imageFile.getInputStream(); // 获取原始流
ImageInputStream imageInputStream = ImageIO.createImageInputStream(fileStream)) { // 正确传递流
if (imageInputStream == null) {
log.error("无法创建ImageInputStream:输入流不可读");
return null;
}
Iterator<ImageReader> readers = ImageIO.getImageReaders(imageInputStream);
if (!readers.hasNext()) {
log.error("Cannot detect image format by ImageIO.getImageReaders" );
return ImageUtils.getImageFormatByHeader( imageFile );
}
// 获取格式名称(如 "JPEG", "PNG")
return readers.next().getFormatName().toUpperCase();
} catch (IOException e) {
log.error("图片格式检测失败", e);
return null;
}
}
/**
* 多次调用该方法获取 multipartFile 表示图片的图片格式不会影响后续对 multipartFile 的使用,
* 因为 Spring 的 MultipartFile 实现(如 StandardMultipartFile)默认基于临时文件存储上传内容,这使得:
* 每次调用 getInputStream() 会返回一个新的 InputStream,从头开始读取文件。
* 流的独立性:每个 InputStream 实例独立读取文件,互不影响。
* 每次 getInputStream():生成新的文件输入流,读取前 12 字节后关闭流。
* 不影响后续操作:所有读取操作均基于独立的流,文件指针始终从头开始。
* @param multipartFile
* @return
*/
public static String getImageFormatByHeader(MultipartFile multipartFile) {
// 验证文件有效性
if (multipartFile == null || multipartFile.isEmpty()) {
log.error("MultipartFile is null or empty");
return null;
}
byte[] header = new byte[12];
try (InputStream inputStream = multipartFile.getInputStream()) {
// 1. 读取前12字节作为header
int headerBytesRead = inputStream.read(header);
if (headerBytesRead < 12) {
header = Arrays.copyOf(header, headerBytesRead);
}
} catch (IOException e) {
log.error(CommonConstans.EXCEPTION_LOG_PREFIX, e);
return null;
}
// 格式检测逻辑
if (isWebP(header)) {
return "WEBP";
} else if (isPNG(header)) {
return "PNG";
} else if (isGIF(header)) {
return "GIF";
} else if (isTIFF(header)) {
return "TIFF";
} else if (isBMP(header)) {
return "BMP";
} else if (isJPEG(header)) {
return "JPEG";
}
return null;
}
public static String getImageFormatName_v4( String imageFilePath ) {
return ImageUtils.getImageFormatName_v1( new File( imageFilePath ) );
}
import cn.hutool.core.codec.Base64;
import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifIFD0Directory;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;
import javax.imageio.*;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
import javax.net.ssl.*;
import javax.xml.bind.DatatypeConverter;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
更多推荐
所有评论(0)