java处理旋转角度的图片
Java读取图片EXIF信息的方法:
首先介绍一下什么是EXIF,EXIF是Exchangeable Image File的缩写,这是一种专门为数码相机照片设定的格式。这种格式可以用来记录数字照片的属性信息,例如相机的品牌及型号、相片的拍摄时间、拍摄时所设置 的光圈大小、快门速度、ISO等等信息。除此之外它还能够记录拍摄数据,以及照片格式化方式,这样就可以输出到兼容EXIF格式的外设上,例如照片打印机 等。
目前最常见的支持EXIF信息的图片格式是JPG,很多的图像工具都可以直接显示图片的EXIF信息,包括现在的一些著名的相册网站也提供页面用于 显示照片的EXIF信息。本文主要介绍Java语言如何读取图像的EXIF信息,包括如何根据EXIF信息对图像进行调整以适合用户浏览。
目前最简单易用的EXIF信息处理的Java包是Drew Noakes写的metadata-extractor,需要注意的是,并不是每个JPG图像文件都包含有EXIF信息,你可以在Windows资源管理器单击选中图片后,如果该图片包含EXIF信息,则会在属性->摘要中显示出来。
首先导入依赖,高版本已不支持,
<dependency>
<groupId>com.drewnoakes</groupId>
<artifactId>metadata-extractor</artifactId>
<version>2.4.0-beta-1</version>
</dependency>
打包需要注意依赖无法打入需要手动打入
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<compilerArguments>
<verbose />
<bootclasspath>${java.home}\lib\rt.jar${path.separator}${java.home}\lib\jce.jar${path.separator}</bootclasspath>
</compilerArguments>
</configuration>
</plugin>
旋转工具类
下面展示处理代码工具类`。
public class RotateImageUtil {
/**
*
* @param bufferedImage
* 图片
* @param angel
* 旋转角度
* @return
*/
public static BufferedImage rotateImage(BufferedImage bufferedImage, int angel,int imageWidth ,int imageHeight ) {
if (bufferedImage == null) {
return null;
}
if (angel < 0) {
// 将负数角度,纠正为正数角度
angel = angel + 360;
}
// 计算重新绘制图片的尺寸
Rectangle rectangle = calculatorRotatedSize(new Rectangle(new Dimension(imageWidth, imageHeight)), angel);
// 获取原始图片的透明度
int type = bufferedImage.getColorModel().getTransparency();
BufferedImage newImage = null;
newImage = new BufferedImage(rectangle.width, rectangle.height, type);
Graphics2D graphics = newImage.createGraphics();
// 平移位置
graphics.translate((rectangle.width - imageWidth) / 2, (rectangle.height - imageHeight) / 2);
// 旋转角度
graphics.rotate(Math.toRadians(angel), imageWidth / 2, imageHeight / 2);
// 绘图
graphics.drawImage(bufferedImage, null, null);
return newImage;
}
/**
* 旋转图片
*
* @param image
* 图片
* @param angel
* 旋转角度
* @return
*/
public static BufferedImage rotateImage(Image image, int angel) {
if (image == null) {
return null;
}
if (angel < 0) {
// 将负数角度,纠正为正数角度
angel = angel + 360;
}
int imageWidth = image.getWidth(null);
int imageHeight = image.getHeight(null);
Rectangle rectangle = calculatorRotatedSize(new Rectangle(new Dimension(imageWidth, imageHeight)), angel);
BufferedImage newImage = null;
newImage = new BufferedImage(rectangle.width, rectangle.height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = newImage.createGraphics();
// transform
graphics.translate((rectangle.width - imageWidth) / 2, (rectangle.height - imageHeight) / 2);
graphics.rotate(Math.toRadians(angel), imageWidth / 2, imageHeight / 2);
graphics.drawImage(image, null, null);
return newImage;
}
/**
* 计算旋转后的尺寸
*
* @param src
* @param angel
* @return
*/
private static Rectangle calculatorRotatedSize(Rectangle src, int angel) {
if (angel >= 90) {
if (angel / 90 % 2 == 1) {
int temp = src.height;
src.height = src.width;
src.width = temp;
}
angel = angel % 90;
}
double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
double angel_dalta_width = Math.atan((double) src.height / src.width);
double angel_dalta_height = Math.atan((double) src.width / src.height);
int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_width));
int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_height));
int des_width = src.width + len_dalta_width * 2;
int des_height = src.height + len_dalta_height * 2;
return new java.awt.Rectangle(new Dimension(des_width, des_height));
}
/**
* 获取网络图片流(附加)
*
* @param url
* @return
*/
public static InputStream getImageStream(String url) {
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setReadTimeout(5000);
connection.setConnectTimeout(5000);
connection.setRequestMethod("GET");
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
return inputStream;
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
具体使用
其中的file是指上传的MultipartFile
我们将MultipartFile写入了一个临时文件中
对临时文件获取了其exif信息,根据exif信息确定了旋转的
然后对临时文件旋转之后又再次写入临时文件中
File file2 = multipartFileToFile(multipartFile); //获取文件流
BufferedImage originalImg = ImageIO.read(multipartFile.getInputStream());
int imageWidth = originalImg.getWidth();
int imageHeight = originalImg.getHeight();
Metadata metadata = JpegMetadataReader.readMetadata(file2);
Directory directory = metadata.getDirectory(ExifDirectory.class);
if(directory.containsTag(ExifDirectory.TAG_ORIENTATION)){ // Exif信息中有保存方向,把信息复制到缩略图
int orientation = 0; // 原图片的方向信息
orientation = directory.getInt(ExifDirectory.TAG_ORIENTATION);
if(6 == orientation) {//翻转了90°和270°的,长宽对调
imageWidth = originalImg.getHeight();//上传图片的宽
imageHeight = originalImg.getWidth(); //上传图片的高
BufferedImage newImage = RotateImageUtil.rotateImage(originalImg,90,imageHeight,imageWidth);
inputStream = bufferedImageToInputStream(newImage);
}else if(orientation==0||orientation==1) {
//360;
} else if(orientation==3) {
//180;
}else if(orientation==8) {
//270;
}
}