@@ -1,17 +1,21 @@
package org.dromara.sis.sdk.e8.utils ;
import com.drew.imaging.ImageMetadataReader ;
import com.drew.imaging.ImageProcessingException ;
import com.drew.metadata.Metadata ;
import com.drew.metadata.MetadataException ;
import com.drew.metadata.exif.ExifIFD0Directory ;
import org.springframework.stereotype.Component ;
import javax.imageio.IIOImage ;
import javax.imageio.ImageIO ;
import javax.imageio.ImageWriteParam ;
import javax.imageio.ImageWriter ;
import javax.imageio.* ;
import javax.imageio.stream.ImageInputStream ;
import javax.imageio.stream.MemoryCacheImageOutputStream ;
import java.awt.* ;
import java.awt.image.BufferedImage ;
import java.io.ByteArrayInputStream ;
import java.io.ByteArrayOutputStream ;
import java.io.IOException ;
import java.util.Iterator ;
/**
* @author lsm
@@ -22,7 +26,8 @@ import java.io.IOException;
public class ImageUtil {
public byte [ ] compressImageToRequirements ( byte [ ] imageData ) throws IOException {
BufferedImage image = ImageIO . read ( new ByteArrayInputStream ( imageData ) ) ;
// 读取图片并处理方向
BufferedImage image = readAndFixOrientation ( imageData ) ;
// 第一步: 调整分辨率( 不超过1000x1000)
if ( image . getWidth ( ) > 1000 | | image . getHeight ( ) > 1000 ) {
@@ -91,6 +96,124 @@ public class ImageUtil {
return resizedImage ;
}
/**
* 读取图片并处理 EXIF 方向信息
*/
private BufferedImage readAndFixOrientation ( byte [ ] imageData ) throws IOException {
try {
// 使用 metadata-extractor 读取 EXIF 方向信息
Metadata metadata = ImageMetadataReader . readMetadata ( new ByteArrayInputStream ( imageData ) ) ;
ExifIFD0Directory directory = metadata . getFirstDirectoryOfType ( ExifIFD0Directory . class ) ;
int orientation = 1 ; // 默认正常方向
if ( directory ! = null & & directory . containsTag ( ExifIFD0Directory . TAG_ORIENTATION ) ) {
orientation = directory . getInt ( ExifIFD0Directory . TAG_ORIENTATION ) ;
}
// 读取图片
ImageInputStream input = ImageIO . createImageInputStream ( new ByteArrayInputStream ( imageData ) ) ;
Iterator < ImageReader > readers = ImageIO . getImageReaders ( input ) ;
if ( ! readers . hasNext ( ) ) {
throw new IOException ( " No ImageReader found for image data " ) ;
}
ImageReader reader = readers . next ( ) ;
reader . setInput ( input ) ;
BufferedImage image = reader . read ( 0 ) ;
reader . dispose ( ) ;
// 根据方向信息旋转图片
return rotateImageAccordingToOrientation ( image , orientation ) ;
} catch ( ImageProcessingException e ) {
throw new IOException ( " Failed to process image metadata " , e ) ;
} catch ( MetadataException e ) {
throw new RuntimeException ( e ) ;
}
}
/**
* 根据方向信息旋转图片
*/
private BufferedImage rotateImageAccordingToOrientation ( BufferedImage image , int orientation ) {
int width = image . getWidth ( ) ;
int height = image . getHeight ( ) ;
return switch ( orientation ) {
case 1 - > // 正常
image ;
case 2 - > // 水平翻转
flipImage ( image , true , false ) ;
case 3 - > // 旋转180度
rotateImage ( image , 180 ) ;
case 4 - > // 垂直翻转
flipImage ( image , false , true ) ;
case 5 - > {
image = flipImage ( image , true , false ) ;
yield rotateImage ( image , 270 ) ;
}
case 6 - > // 旋转90度
rotateImage ( image , 90 ) ;
case 7 - > {
image = flipImage ( image , true , false ) ;
yield rotateImage ( image , 90 ) ;
}
case 8 - > // 旋转270度
rotateImage ( image , 270 ) ;
default - > image ;
} ;
}
/**
* 旋转图片
*/
private BufferedImage rotateImage ( BufferedImage image , double degrees ) {
double radians = Math . toRadians ( degrees ) ;
double sin = Math . abs ( Math . sin ( radians ) ) ;
double cos = Math . abs ( Math . cos ( radians ) ) ;
int width = image . getWidth ( ) ;
int height = image . getHeight ( ) ;
int newWidth = ( int ) Math . floor ( width * cos + height * sin ) ;
int newHeight = ( int ) Math . floor ( height * cos + width * sin ) ;
BufferedImage rotated = new BufferedImage ( newWidth , newHeight , image . getType ( ) ) ;
Graphics2D g = rotated . createGraphics ( ) ;
g . translate ( ( newWidth - width ) / 2 , ( newHeight - height ) / 2 ) ;
g . rotate ( Math . toRadians ( degrees ) , width / 2 . 0 , height / 2 . 0 ) ;
g . drawRenderedImage ( image , null ) ;
g . dispose ( ) ;
return rotated ;
}
/**
* 翻转图片
*/
private BufferedImage flipImage ( BufferedImage image , boolean horizontal , boolean vertical ) {
int width = image . getWidth ( ) ;
int height = image . getHeight ( ) ;
BufferedImage flipped = new BufferedImage ( width , height , image . getType ( ) ) ;
Graphics2D g = flipped . createGraphics ( ) ;
if ( horizontal & & vertical ) {
g . drawImage ( image , width , height , - width , - height , null ) ;
} else if ( horizontal ) {
g . drawImage ( image , width , 0 , - width , height , null ) ;
} else if ( vertical ) {
g . drawImage ( image , 0 , height , width , - height , null ) ;
} else {
g . drawImage ( image , 0 , 0 , null ) ;
}
g . dispose ( ) ;
return flipped ;
}
private byte [ ] compressWithQuality ( BufferedImage image , float quality ) throws IOException {
// 获取JPEG编码器
ImageWriter writer = ImageIO . getImageWritersByFormatName ( " jpeg " ) . next ( ) ;