最近做项目需要图片压缩处理,网上找的方法大都使用了 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/