java圖片壓縮,使用ImageIO代替JPEGImageEncoder

NO IMAGE
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

最近做專案需要圖片壓縮處理,網上找的方法大都使用了 com.sun.image.codec.jpeg.* 這個包中的JPEGImageEncoder類,引入這個包後一直報錯,各種google百度,嘗試了各種方法,包括手動引jre中的rt.jar,以及在eclipse中把受訪問限制的API提示從ERROR改為WARNING,等等,然而這些都是不好使的,因為後來我發現我的java-7-openjdk-amd64中的rt.jar裡邊根本就沒有com.sun.image.*,貌似這個類在java7中已經被徹底remove了,至少我這個版本是沒有了。然後搜了個使用ImageIO類來進行處理的替代方案,程式碼如下:

import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.awt.*;
//舊的jpeg處理類
//import com.sun.image.codec.jpeg.*; 
import java.awt.image.BufferedImage;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;
import org.w3c.dom.Element;
import com.sun.imageio.plugins.jpeg.*;
/**
 * @author zhouqz
 */
public class ImgCompressUtil {
/**
 * log4j
 */
private final static Logger logger = Logger.getLogger(ImgCompressUtil.class
.getName());
/**
 * 圖片壓縮測試
 * 
 * @param args
 */
public static void main(String args[]) {
// 圖片url,壓縮後的寬和高
String url = "/upload/c671c57023e6eb83a1fa492babf0779e.jpg";
int w = 700;
int h = 500;
//壓縮後的圖片路徑
String newName = MD5Util.encodeMD5(url);
String newDir = "/var/imgcompress/";
String filePath = newDir   newName   "_"
 w   "_"   h   url.substring(url.indexOf("."));
//壓縮
ImgCompress(url,filePath,w,h);
}
/**
 * 外部呼叫方法
 * @param url
 * @param w
 * @param h
 */
public static String ImgCompress(String url, String filePath, int w, int h) {
// 壓縮質量 百分比
float JPEGcompression = 0.7f;
// 本地圖片儲存路徑
url = "/var"   url;
String name = url.substring(url.lastIndexOf("/")   1);
// 擷取url中最後一個“/”之後的字串為name
logger.info("url:==========="   url);
logger.info("name:========="   name);
//壓縮主方法
 return ImgCompress(filePath, url, name, w, h, JPEGcompression);
}
/**
 * 圖片壓縮主方法
 * 
 * @param newDir
 *            圖片所在的資料夾路徑
 * @param file
 *            圖片路徑
 * @param name
 *            圖片名
 * @param w
 *            目標寬
 * @param h
 *            目標高
 * @param JPEGcompression
 *            壓縮質量/百分比
 * @author zhouqz
 */
public static String ImgCompress(String filePath, String url, String name,
int w, int h, float JPEGcompression) {
File file = new File(url);
if (!(file.exists() && file.canRead())) {
filePath = "/var/upload/404.jpg";
}else{
try {
BufferedImage bufferedImage =  ImageIO.read(file);
//註釋掉的部分是將壓縮後的影象調整為方形
//				int old_w = bufferedImage.getWidth(null); // 得到源圖寬
//				int old_h = bufferedImage.getHeight(null);//得到源圖高
//				int new_w = 0;
//				int new_h = 0; 
//				double w2 = (old_w * 1.00) / (w * 1.00);
//				double h2 = (old_h * 1.00) / (h * 1.00);
//				// 圖片跟據長寬留白,成一個正方形圖。
//				BufferedImage oldpic;
//				if (old_w > old_h) {
//					oldpic = new BufferedImage(old_w, old_w,
//							BufferedImage.TYPE_INT_RGB);
//				} else {
//					if (old_w < old_h) {
//						oldpic = new BufferedImage(old_h, old_h,
//								BufferedImage.TYPE_INT_RGB);
//					} else {
//						oldpic = new BufferedImage(old_w, old_h,
//								BufferedImage.TYPE_INT_RGB);
//					}
//				}
//				Graphics2D g = oldpic.createGraphics();
//				g.setColor(Color.white);
//				if (old_w > old_h) {
//					g.fillRect(0, 0, old_w, old_w);
//					g.drawImage(src, 0, (old_w - old_h) / 2, old_w, old_h,
//							Color.white, null);
//				} else {
//					if (old_w < old_h) {
//						g.fillRect(0, 0, old_h, old_h);
//						g.drawImage(src, (old_h - old_w) / 2, 0, old_w, old_h,
//								Color.white, null);
//					} else {
//						// g.fillRect(0,0,old_h,old_h);
//						g.drawImage(src.getScaledInstance(old_w, old_h,
//								Image.SCALE_SMOOTH), 0, 0, null);
//					}
//				}
//				g.dispose();
//				src = oldpic;
// 圖片調整為方形結束
//				if (old_w > w)
//					new_w = (int) Math.round(old_w / w2);
//				else
//					new_w = old_w;
//				if (old_h > h)
//					new_h = (int) Math.round(old_h / h2);// 計算新圖長寬
//				else
//					new_h = old_h;
int new_w = w;
int new_h = h; 
BufferedImage image_to_save = new BufferedImage(new_w, new_h,
bufferedImage.getType());
image_to_save.getGraphics().drawImage(
bufferedImage.getScaledInstance(new_w, new_h, Image.SCALE_SMOOTH), 0,
0, null);
FileOutputStream fos = new FileOutputStream(filePath); // 輸出到檔案流
// 舊的使用 jpeg classes進行處理的方法
// JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(fos);
// JPEGEncodeParam jep =
// JPEGCodec.getDefaultJPEGEncodeParam(image_to_save);
/* 壓縮質量 */
// jep.setQuality(per, true);
// encoder.encode(image_to_save, jep);
// 新的方法
int dpi = 300;//解析度
saveAsJPEG(dpi, image_to_save, JPEGcompression, fos);
//關閉輸出流
fos.close();
//返回壓縮後的圖片地址
} catch (IOException ex) {
logger.log(Level.SEVERE, null, ex);
filePath = "/var/upload/404.jpg";
}
}
return filePath;
}
/**
 * 以JPEG編碼儲存圖片
 * 
 * @param dpi
 *            解析度
 * @param image_to_save
 *            要處理的影象圖片
 * @param JPEGcompression
 *            壓縮比
 * @param fos
 *            檔案輸出流
 * @throws IOException
 */
public static void saveAsJPEG(Integer dpi, BufferedImage image_to_save,
float JPEGcompression, FileOutputStream fos) throws IOException {
// useful documentation at
// http://docs.oracle.com/javase/7/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.html
// useful example program at
// http://johnbokma.com/java/obtaining-image-metadata.html to output
// JPEG data
// old jpeg class
// com.sun.image.codec.jpeg.JPEGImageEncoder jpegEncoder =
// com.sun.image.codec.jpeg.JPEGCodec.createJPEGEncoder(fos);
// com.sun.image.codec.jpeg.JPEGEncodeParam jpegEncodeParam =
// jpegEncoder.getDefaultJPEGEncodeParam(image_to_save);
// Image writer
JPEGImageWriter imageWriter = (JPEGImageWriter) ImageIO
.getImageWritersBySuffix("jpg").next();
ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
imageWriter.setOutput(ios);
// and metadata
IIOMetadata imageMetaData = imageWriter.getDefaultImageMetadata(
new ImageTypeSpecifier(image_to_save), null);
// if(dpi != null && !dpi.equals("")){
//
// //old metadata
// //jpegEncodeParam.setDensityUnit(com.sun.image.codec.jpeg.JPEGEncodeParam.DENSITY_UNIT_DOTS_INCH);
// //jpegEncodeParam.setXDensity(dpi);
// //jpegEncodeParam.setYDensity(dpi);
//
// //new metadata
// Element tree = (Element)
// imageMetaData.getAsTree("javax_imageio_jpeg_image_1.0");
// Element jfif =
// (Element)tree.getElementsByTagName("app0JFIF").item(0);
// jfif.setAttribute("Xdensity", Integer.toString(dpi) );
// jfif.setAttribute("Ydensity", Integer.toString(dpi));
//
// }
if (JPEGcompression >= 0 && JPEGcompression <= 1f) {
// old compression
// jpegEncodeParam.setQuality(JPEGcompression,false);
// new Compression
JPEGImageWriteParam jpegParams = (JPEGImageWriteParam) imageWriter
.getDefaultWriteParam();
jpegParams.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
jpegParams.setCompressionQuality(JPEGcompression);
}
// old write and clean
// jpegEncoder.encode(image_to_save, jpegEncodeParam);
// new Write and clean up
imageWriter.write(imageMetaData,
new IIOImage(image_to_save, null, null), null);
ios.close();
imageWriter.dispose();
}
}

參考:

http://jiangpin1987.iteye.com/blog/749690

https://blog.idrsolutions.com/2012/05/replacing-the-deprecated-java-jpeg-classes-for-java-7/

程式語言 最新文章