package img; import java.awt.Color; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; 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.io.OutputStream; import javax.imageio.ImageIO; import javax.media.jai.PlanarImage; import org.apache.commons.io.IOUtils; import com.alibaba.simpleimage.ImageFormat; import com.alibaba.simpleimage.ImageWrapper; import com.alibaba.simpleimage.SimpleImageException; import com.alibaba.simpleimage.render.CropParameter; import com.alibaba.simpleimage.render.ScaleParameter; import com.alibaba.simpleimage.render.WriteParameter; import com.alibaba.simpleimage.render.ScaleParameter.Algorithm; import com.alibaba.simpleimage.util.ImageCropHelper; import com.alibaba.simpleimage.util.ImageReadHelper; import com.alibaba.simpleimage.util.ImageScaleHelper; import com.alibaba.simpleimage.util.ImageWriteHelper; /** * 图片的压缩、裁剪 */ public class Test { public static void main(String[] args) throws Exception { // 输入输出文件路径/文件 String src = "D:\\test\\map.jpg"; String dest = "D:\\test\\map1.jpg"; File srcFile = new File(src); File destFile = new File(dest); // 将输入文件转换为字节数组 byte[] bytes = getByte(srcFile); // 构造输入输出字节流 ByteArrayInputStream is = new ByteArrayInputStream(bytes); ByteArrayOutputStream os = new ByteArrayOutputStream(); // 处理图片 zoomAndCut2(is, os, 400, 400); // 将字节输出流写到输出文件路径下 writeFile(os, destFile); } /** * 按固定长宽进行缩放 * @param is 输入流 * @param os 输出流 * @param width 指定长度 * @param height 指定宽度 * @throws Exception */ public static void zoomImage(InputStream is, OutputStream os, int width, int height) throws Exception { //读取图片 BufferedImage bufImg = ImageIO.read(is); is.close(); //获取缩放比例 double wRatio = width * 1.0/ bufImg.getWidth(); double hRatio = height * 1.0 / bufImg.getHeight(); AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(wRatio, hRatio), null); BufferedImage bufferedImage = ato.filter(bufImg, null); //写入缩减后的图片 ImageIO.write(bufferedImage, "jpg", os); } /** * 按固定文件大小进行缩放 * @param is 输入流 * @param os 输出流 * @param size 文件大小指定 * @throws Exception */ public static void zoomImage(InputStream is, OutputStream os, Integer size) throws Exception { /*FileInputStream的available()方法返回的是int类型,当数据大于1.99G(2147483647字节)后将无法计量, 故求取流文件大小最好的方式是使用FileChannel的size()方法,其求取结果与File的length()方法的结果一致 参考:http://blog.csdn.net/chaijunkun/article/details/22387305*/ int fileSize = is.available(); //文件大于size时,才进行缩放。注意:size以K为单位 if(fileSize < size * 1024){ return; } // 获取长*宽(面积)缩放比例 double sizeRate = (size * 1024 * 0.5) / fileSize; // 获取长和宽分别的缩放比例,即面积缩放比例的2次方根 double sideRate = Math.sqrt(sizeRate); BufferedImage bufImg = ImageIO.read(is); AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(sideRate, sideRate), null); BufferedImage bufferedImage = ato.filter(bufImg, null); ImageIO.write(bufferedImage, "jpg", os); } /** * 等比例缩放,以宽或高较大者达到指定长度为准 * @param src 输入文件路径 * @param dest 输出文件路径 * @param width 指定宽 * @param height 指定高 */ public static void zoomTo400(String src, String dest, Integer width, Integer height){ try { File srcFile = new File(src); File destFile = new File(dest); BufferedImage bufImg = ImageIO.read(srcFile); int w0 = bufImg.getWidth(); int h0 = bufImg.getHeight(); // 获取较大的一个缩放比率作为整体缩放比率 double wRatio = 1.0 * width / w0; double hRatio = 1.0 * height / h0; double ratio = Math.min(wRatio, hRatio); // 缩放 AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null); BufferedImage bufferedImage = ato.filter(bufImg, null); // 输出 ImageIO.write(bufferedImage, dest.substring(dest.lastIndexOf(".")+1), destFile); } catch (IOException e) { e.printStackTrace(); } } /** * 等比例图片压缩,以宽或高较大者达到指定长度为准 * @param is 输入流 * @param os 输出流 * @param width 宽 * @param height 高 * @throws IOException */ public static void changeSize(InputStream is, OutputStream os, int width, int height) throws IOException { BufferedImage bis = ImageIO.read(is); // 构造Image对象 is.close(); int srcWidth = bis.getWidth(null); // 得到源图宽 int srcHeight = bis.getHeight(null); // 得到源图高 if (width <= 0 || width > srcWidth) { width = bis.getWidth(); } if (height <= 0 || height > srcHeight) { height = bis.getHeight(); } // 若宽高小于指定最大值,不需重新绘制 if (srcWidth <= width && srcHeight <= height) { ImageIO.write(bis, "jpg", os); os.close(); } else { double scale = ((double) width / srcWidth) > ((double) height / srcHeight) ? ((double) height / srcHeight) : ((double) width / srcWidth); width = (int) (srcWidth * scale); height = (int) (srcHeight * scale); BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); bufferedImage.getGraphics().drawImage(bis, 0, 0, width, height, Color.WHITE, null); // 绘制缩小后的图 ImageIO.write(bufferedImage, "jpg", os); os.close(); } } /** * 先等比例缩放,小边缩放至指定长度后, 大边直接裁剪指指定长度 * @param is * @param os * @param width * @param height */ public final static void zoomAndCut1(InputStream is, OutputStream os, int width, int height) throws SimpleImageException { // 读文件 ImageWrapper imageWrapper = ImageReadHelper.read(is); int w = imageWrapper.getWidth(); int h = imageWrapper.getHeight(); double wRatio = 1.0 * width / w; double hRatio = 1.0 * height / h; double ratio = Math.max(wRatio, hRatio); /*1.缩放*/ // 缩放参数 如果图片宽和高都小于目标图片则不做缩放处理 ScaleParameter scaleParam = null; if (w < width && h < height) { scaleParam = new ScaleParameter(w, h, Algorithm.LANCZOS); } // 为防止强转int时小数部分丢失,故加1,防止出现异常错误 scaleParam = new ScaleParameter((int)(w * ratio) + 1, (int)(h * ratio) + 1, Algorithm.LANCZOS); // 缩放 PlanarImage planarImage = ImageScaleHelper.scale(imageWrapper.getAsPlanarImage(), scaleParam); /*2.裁切*/ // 获取裁剪偏移量 imageWrapper = new ImageWrapper(planarImage); int w2 = imageWrapper.getWidth(); int h2 = imageWrapper.getHeight(); int x = (w2 - width) / 2; int y = (h2 - height) / 2; // 裁切参数 如果图片宽和高都小于目标图片则处理 CropParameter cropParam = new CropParameter(x, y, width, height); if (x < 0 || y < 0) { cropParam = new CropParameter(0, 0, w, h); } // 裁剪 planarImage = ImageCropHelper.crop(planarImage, cropParam); /*输出*/ imageWrapper = new ImageWrapper(planarImage); String prefix = "jpg"; ImageWriteHelper.write(imageWrapper, os, ImageFormat.getImageFormat(prefix), new WriteParameter()); } /** * 先等比例缩放,小边缩放至指定长度后, 大边直接裁剪指指定长度 * @param is * @param os * @param width * @param height */ public static void zoomAndCut2(InputStream is, OutputStream os, Integer width, Integer height) throws IOException, SimpleImageException{ // 读文件 BufferedImage bufferedImage = ImageIO.read(is); int w = bufferedImage.getWidth(); int h = bufferedImage.getHeight(); // 获取缩放比例 double wRatio = 1.0 * width / w; double hRatio = 1.0 * height / h; double ratio = Math.max(wRatio, hRatio); // 缩放 AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null); bufferedImage = ato.filter(bufferedImage, null); // 对象转换 ImageWrapper imageWrapper = new ImageWrapper(bufferedImage); // 获得裁剪偏移量 int w2 = imageWrapper.getWidth(); int h2 = imageWrapper.getHeight(); float x = (w2 - width) / 2.0f; float y = (h2 - height) / 2.0f; // 裁剪参数 如果图片宽和高都小于目标图片则处理 CropParameter cropParameter = new CropParameter(x, y, width, height); if (x < 0 && y < 0) { cropParameter = new CropParameter(0, 0, width, height); } PlanarImage crop = ImageCropHelper.crop(imageWrapper.getAsPlanarImage(), cropParameter); imageWrapper = new ImageWrapper(crop); // 后缀 String prefix = "jpg"; // 写文件 ImageWriteHelper.write(imageWrapper, os, ImageFormat.getImageFormat(prefix), new WriteParameter()); } /** * 从中间裁切需要的大小 * @param is * @param os * @param width * @param height */ public static void CutCenter(InputStream is, OutputStream os, Integer width, Integer height) { try { ImageWrapper imageWrapper = ImageReadHelper.read(is); int w = imageWrapper.getWidth(); int h = imageWrapper.getHeight(); int x = (w - width) / 2; int y = (h - height) / 2; CropParameter cropParam = new CropParameter(x, y, width, height);// 裁切参数 if (x < 0 || y < 0) { cropParam = new CropParameter(0, 0, w, h);// 裁切参数 } PlanarImage planrImage = ImageCropHelper.crop(imageWrapper.getAsPlanarImage(), cropParam); imageWrapper = new ImageWrapper(planrImage); String prefix = "JPG"; ImageWriteHelper.write(imageWrapper, os, ImageFormat.getImageFormat(prefix), new WriteParameter()); } catch (Exception e) { e.printStackTrace(); } finally { IOUtils.closeQuietly(is); } } /** * 将file文件转为字节数组 * @param file * @return */ public static byte[] getByte(File file){ byte[] bytes = null; try { FileInputStream fis = new FileInputStream(file); bytes = new byte[fis.available()]; fis.read(bytes); fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return bytes; } /** * 将字节流写到指定文件 * @param os * @param file */ public static void writeFile(ByteArrayOutputStream os, File file){ FileOutputStream fos = null; try { byte[] bytes = os.toByteArray(); if (file.exists()) { file.delete(); } fos = new FileOutputStream(file); fos.write(bytes); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }