java 使用metadata-extractor 旋轉圖片 ...
package test;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel;
import java.util.Iterator;
import org.apache.log4j.Logger;
import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifIFD0Directory;
import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
public class Test {
private static Logger logger = Logger.getLogger(Test.class);
public static void main(String args[]) {
String src = "d:/2.jpg";
//獲取圖片旋轉角度
int angel = getRotateAngleForPhoto(src);
if (angel>0) {
rotateImage(new File(src), angel);
}
}
/**
* 圖片翻轉時,計算圖片翻轉到正常顯示需旋轉角度
*/
public static int getRotateAngleForPhoto(String fileName){
File file = new File(fileName);
int angel = 0;
InputStream is = null;
try {
is = new FileInputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try{
//核心對象操作對象
Metadata metadata = ImageMetadataReader.readMetadata(is);
//獲取所有不同類型的Directory,如ExifSubIFDDirectory, ExifInteropDirectory, ExifThumbnailDirectory等,這些類均為ExifDirectoryBase extends Directory子類
//分別遍歷每一個Directory,根據Directory的Tags就可以讀取到相應的信息
int orientation = 0;
Iterable<Directory> iterable = metadata.getDirectories();
for (Iterator<Directory> iter = iterable.iterator();iter.hasNext();) {
Directory dr = iter.next();
if (dr.getString(ExifIFD0Directory.TAG_ORIENTATION)!=null) {
orientation = dr.getInt(ExifIFD0Directory.TAG_ORIENTATION);
}
logger.debug("orientation=="+orientation);
/*Collection<Tag> tags = dr.getTags();
for (Tag tag : tags) {
System.out.println(tag.getTagName() + ": " + tag.getDescription());
}*/
}
if(orientation==0||orientation==1) {
angel=360;
}
else if(orientation==3) {
angel=180;
}
else if(orientation==6) {
angel=90;
}
else if(orientation==8) {
angel=270;
}
} catch(Exception e){
e.printStackTrace();
}
logger.info("圖片旋轉角度:" + angel);
return angel;
}
/**
* 旋轉圖片為指定角度
*
* @param bufferedimage
* 目標圖像
* @param degree
* 旋轉角度
* @return
*/
public static File rotateImage(File file, final int angel) {
BufferedImage src = InputImage(file.getPath());
BufferedImage bi = null;
/*int w = bufferedimage.getWidth();
int h = bufferedimage.getHeight();
int type = bufferedimage.getColorModel().getTransparency();
BufferedImage img;
Graphics2D graphics2d;
(graphics2d = (img = new BufferedImage(w, h, type))
.createGraphics()).setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2d.rotate(Math.toRadians(degree), w * 0.99, h * 0.99);
graphics2d.drawImage(bufferedimage, 0, 0, null);
graphics2d.dispose();*/
int src_width = src.getWidth(null);
int src_height = src.getHeight(null);
Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension(src_width, src_height)), angel);
bi = new BufferedImage(rect_des.width, rect_des.height,BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = bi.createGraphics();
g2.translate((rect_des.width - src_width) / 2,
(rect_des.height - src_height) / 2);
g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);
g2.drawImage(src, null, null);
// 調用方法輸出圖片文件
OutImage(file.getPath(), bi, (float)0.5);
return file;
}
/**
* 計算旋轉參數
*/
public static Rectangle CalcRotatedSize(Rectangle src,int angel){
// if angel is greater than 90 degree,we need to do some conversion.
if(angel > 90){
if(angel / 9%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 outImgPath
* @param newImg
* @param per
*/
private static void OutImage(String outImgPath, BufferedImage newImg,
float per) {
// 判斷輸出的文件夾路徑是否存在,不存在則創建
File file = new File(outImgPath);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}// 輸出到文件流
FileChannel fc= null;
try {
FileOutputStream newimage = new FileOutputStream(outImgPath);
//獲取圖片大小
fc= newimage.getChannel();
logger.info("圖片大小:"+fc.size()/1024/1024+"M");
if (fc.size()>1*1024*1024) {//1M
per = (float) (1*1024*1024.00/fc.size()*0.5);
}
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(newimage);
JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(newImg);
// 壓縮質量
jep.setQuality(per, true);
encoder.encode(newImg, jep);
newimage.close();
} catch (FileNotFoundException e) {
logger.error(e);
// TODO Auto-generated catch blocke.printStackTrace();
} catch (ImageFormatException e) {
logger.error(e);
// TODO Auto-generated catch blocke.printStackTrace();
} catch (IOException e) {
logger.error(e);
// TODO Auto-generated catch blocke.printStackTrace();
}
}
/**
* * 圖片文件讀取
*
* @param srcImgPath
* @return
*/
public static BufferedImage InputImage(String srcImgPath) {
//logger.debug(srcImgPath);
BufferedImage srcImage = null;
File file = new File(srcImgPath);
try {
// 構造BufferedImage對象
FileInputStream in = new FileInputStream(file);
byte[] b = new byte[5];
in.read(b);
srcImage = javax.imageio.ImageIO.read(file);
} catch (IOException e) {
System.out.println("讀取圖片文件出錯!" + e.getMessage());
e.printStackTrace();
}
return srcImage;
}
}
附件下載(附metadata-extractor-2.8.1.jar,xmpcore-5.1.2.jar)