pom 依赖:
XML
<dependency>
<groupId>com.drewnoakes</groupId>
<artifactId>metadata-extractor</artifactId>
<version>2.15.0</version>
</dependency>
java 类中的 import 信息:
java
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.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.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
ImageUtils.java 的裁剪图片方法:
java
/**
* 裁切图片
* @param srcImageFilePath
* @param targetImageFilePath
* @param x1 左上角点的 x 坐标
* @param y1 左上角点的 y 坐标
* @param x2 右下角点的 x 坐标
* @param y2 右下角点的 y 坐标
* @return
*/
public static boolean cutImage_v1(String srcImageFilePath, String targetImageFilePath,int x1, int y1, int x2, int y2 ) {
String srcImageFilePath_rotate_tmp = null;
try {
// 获取原图片的旋转角度
int rotateAngle = ImageUtils.getRotateAngle(srcImageFilePath);
if( rotateAngle == 90 || rotateAngle == 180 || rotateAngle == 270 ){
String outputDirPath = MyFileUtils.createImageTmpTodayDir();
srcImageFilePath_rotate_tmp = outputDirPath + MyIdUtils.generateuUniqueStringId() + ".jpg";
// 有时候需要旋转90度,有时候需要旋转180度,有时候需要旋转270度
ImageUtils.rotateImage_v1( srcImageFilePath,srcImageFilePath_rotate_tmp,Double.valueOf( rotateAngle ) );
srcImageFilePath = srcImageFilePath_rotate_tmp;
}
int width = x2 - x1;
int height = y2 - y1;
File srcImageFile = new File(srcImageFilePath);
String imageFormatName = ImageUtils.getImageFormatName_v1( srcImageFile );
// 读取原始图片文件
BufferedImage srcImage = ImageIO.read( srcImageFile );
int type = srcImage.getType();
int height_ = srcImage.getHeight();
int width_ = srcImage.getWidth();
ColorModel colorModel = srcImage.getColorModel();
int transferType = colorModel.getTransferType();
ColorSpace colorSpace = colorModel.getColorSpace();
int colorSpaceType = colorSpace.getType();
int colorSpaceNumComponents = colorSpace.getNumComponents();
log.info( srcImageFilePath + " 的 type = " + type + ",width_ = " + width_ + ",height_ = " + height_ + ",transferType = " + transferType + ",colorSpaceType = " + colorSpaceType + ",colorSpaceNumComponents = " + colorSpaceNumComponents + ",imageFormatName = " + imageFormatName );
// 创建 BufferedImage 对象
// BufferedImage croppedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
BufferedImage croppedImage = new BufferedImage(width, height, type);
// 进行剪裁操作
Graphics2D graphics = croppedImage.createGraphics();
graphics.drawImage(srcImage, 0, 0, width, height, x1, y1, x1 + width, y1 + height, null);
graphics.dispose();
// 保存剪裁后的图片文件
ImageIO.write(croppedImage, imageFormatName, new File( targetImageFilePath ));
return true;
}catch ( Exception e ){
log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e );
// 裁剪图片失败,删除目标文件
MyFileUtils.deleteFile( targetImageFilePath );
return false;
}finally {
// 无论操作成功与否,都删除临时文件
MyFileUtils.deleteFile( srcImageFilePath_rotate_tmp );
}
}
/**
* 裁切图片
* @param srcImageUrl
* @param targetImageFilePath
* @param x1 左上角点的 x 坐标
* @param y1 左上角点的 y 坐标
* @param x2 右下角点的 x 坐标
* @param y2 右下角点的 y 坐标
* @return
*/
public static boolean cutImage_v2(String srcImageUrl, String targetImageFilePath,int x1, int y1, int x2, int y2 ) {
String outputPath_tmp = null;
try {
// 将源文件下载下来生成临时文件
String outputDir = MyFileUtils.createImageTmpTodayDir();
outputPath_tmp = outputDir + MyIdUtils.generateuUniqueStringId() + ".jpg";
boolean downloadSuccess = ImageUtils.imageUrl2File(srcImageUrl, outputPath_tmp);
if( !downloadSuccess ){
return false;
}
return ImageUtils.cutImage_v1( outputPath_tmp,targetImageFilePath,x1,y1,x2,y2 );
}catch ( Exception e ){
log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e );
// 裁剪图片失败,删除目标文件
MyFileUtils.deleteFile( targetImageFilePath );
return false;
}finally {
// 无论是否成功,都删除临时文件
MyFileUtils.deleteFile( outputPath_tmp );
}
}
获取图片旋转角度的方法:
java
public static int getRotateAngle(String imageFilePath){
try {
File imageFile = new File(imageFilePath);
Metadata metadata = ImageMetadataReader.readMetadata(imageFile);
Directory imageDirectory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
int orientation = imageDirectory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
int rotateAngle = 0;
// 原图片的方向信息
if(6 == orientation ){
//6旋转90
rotateAngle = 90;
}else if( 3 == orientation){
//3旋转180
rotateAngle = 180;
}else if( 8 == orientation){
//8旋转90
rotateAngle = 270;
}
log.info( imageFilePath + " 旋转角度信息为 " + rotateAngle + " 度" );
return rotateAngle;
}catch ( Exception e ){
throw new BusinessLogicException( "操作失败,检测图片旋转角度失败" );
}
}
旋转图片的方法:
java
public static void rotateImage_v1(String inputImagePath,String outputImagePath, double degree) {
try {
// 读取图片
BufferedImage originalImage = ImageIO.read(new File(inputImagePath));
String imageFormatName = getImageFormatName_v1(new File(inputImagePath));
rotateImage_v3( originalImage,outputImagePath,degree,imageFormatName );
}catch ( Exception e ){
log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e );
}
}
public static void rotateImage_v3(BufferedImage inputImage,String outputImagePath, double degree,String savedFormatName) {
try {
// 计算旋转后的新宽高
int width = inputImage.getWidth();
int height = inputImage.getHeight();
double sin = Math.abs(Math.sin(Math.toRadians(degree))),
cos = Math.abs(Math.cos(Math.toRadians(degree)));
int newWidth = (int) Math.floor(width * cos + height * sin),
newHeight = (int) Math.floor(height * cos + width * sin);
// 创建一个新的空白图片用于将原始图片绘制上去
BufferedImage rotatedImage = new BufferedImage(newWidth, newHeight, inputImage.getType());
// 设置旋转转换
AffineTransform at = new AffineTransform();
at.translate((newWidth - width) / 2, (newHeight - height) / 2);
at.rotate(Math.toRadians(degree), width / 2, height / 2);
// 执行旋转
AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_BICUBIC);
rotatedImage = op.filter(inputImage, rotatedImage);
if( savedFormatName == null ){
savedFormatName = "jpg";
}
ImageIO.write(rotatedImage, savedFormatName, new File( outputImagePath) );
}catch ( Exception e ){
log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e );
}
}
ImageUtils.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." );
return null;
}
ImageReader reader = imageReadersList.next();
return reader.getFormatName();
} catch (IOException e) {
log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e );
throw new BusinessLogicException( "失败" );
}
}
下载图片的方法:
java
public static boolean imageUrl2File(String imageUrl, String outputPath) {
imageUrl = MyStringUtils.null2EmptyWithTrim( imageUrl );
outputPath = MyStringUtils.null2EmptyWithTrim( outputPath );
if( imageUrl.length() == 0 || outputPath.length() == 0){
return false;
}
InputStream in = null;
FileOutputStream fos = null;
try {
URL url = new URL(imageUrl);
URLConnection conn = url.openConnection();
in = conn.getInputStream();
fos = new FileOutputStream(outputPath);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
fos.flush();
log.info( "图片 " + imageUrl + " 保存至 " + outputPath );
return true;
} catch (IOException e) {
log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e );
return false;
}finally {
MyFileUtils.closeCloseable( fos );
MyFileUtils.closeCloseable( in );
}
}
MyFileUtils.java:
java
import java.io.*;
@Slf4j
public class MyFileUtils {
public static void deleteFile(String filePath) {
if( filePath == null ){
return;
}
try {
File file = new File(filePath);
if( file.exists() ){
file.delete();
}
}catch ( Exception e ){
log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e );
}
}
}