图片处理工具类 - ImageUtils.java

纯JAVA实现的图片处理工具类,提供图片的裁剪、压缩、获取尺寸、制作圆角等方法。

 

源码如下:(点击下载 -ImageUtils.java 、FolderUtils.java 、commons-io-2.4.jarcommons-lang-2.6.jar)

  1 import java.awt.AlphaComposite;
  2 import java.awt.Color;
  3 import java.awt.Graphics2D;
  4 import java.awt.Image;
  5 import java.awt.RenderingHints;
  6 import java.awt.geom.RoundRectangle2D;
  7 import java.awt.image.BufferedImage;
  8 import java.io.BufferedInputStream;
  9 import java.io.BufferedOutputStream;
 10 import java.io.File;
 11 import java.io.FileInputStream;
 12 import java.io.FileNotFoundException;
 13 import java.io.FileOutputStream;
 14 import java.io.IOException;
 15 import java.io.InputStream;
 16 import java.io.OutputStream;
 17 import java.net.URL;
 18 import java.util.Iterator;
 19 import javax.imageio.IIOImage;
 20 import javax.imageio.ImageIO;
 21 import javax.imageio.ImageWriteParam;
 22 import javax.imageio.ImageWriter;
 23 import javax.imageio.stream.ImageOutputStream;
 24 import org.apache.commons.io.FilenameUtils;
 25 import org.apache.commons.io.IOUtils;
 26 import org.apache.commons.lang.StringUtils;
 27 
 28 /**
 29  * 纯JAVA实现的图片处理工具类
 30  * 
 31  */
 32 public class ImageUtils {
 33 
 34     /**
 35      * 获取图片尺寸信息
 36      * 
 37      * @param filePath
 38      *            a {@link java.lang.String} object.
 39      * @return [width, height]
 40      */
 41     public static int[] getSizeInfo(String filePath) throws Exception {
 42         File file = new File(filePath);
 43         return getSizeInfo(file);
 44     }
 45 
 46     /**
 47      * 获取图片尺寸信息
 48      * 
 49      * @param url
 50      *            a {@link java.net.URL} object.
 51      * @return [width,height]
 52      */
 53     public static int[] getSizeInfo(URL url) throws Exception {
 54         InputStream input = null;
 55         try {
 56             input = url.openStream();
 57             return getSizeInfo(input);
 58         } catch (IOException e) {
 59             e.printStackTrace();
 60             throw new Exception(e);
 61         } finally {
 62             IOUtils.closeQuietly(input);
 63         }
 64     }
 65 
 66     /**
 67      * 获取图片尺寸信息
 68      * 
 69      * @param file
 70      *            a {@link java.io.File} object.
 71      * @return [width,height]
 72      */
 73     public static int[] getSizeInfo(File file) throws Exception {
 74         if (!file.exists()) {
 75             throw new Exception("file " + file.getAbsolutePath() + " doesn't exist.");
 76         }
 77         BufferedInputStream input = null;
 78         try {
 79             input = new BufferedInputStream(new FileInputStream(file));
 80             return getSizeInfo(input);
 81         } catch (FileNotFoundException e) {
 82             e.printStackTrace();
 83             throw new Exception(e);
 84         } finally {
 85             IOUtils.closeQuietly(input);
 86         }
 87     }
 88 
 89     /**
 90      * 获取图片尺寸
 91      * 
 92      * @param input
 93      *            a {@link java.io.InputStream} object.
 94      * @return [width,height]
 95      */
 96     public static int[] getSizeInfo(InputStream input) throws Exception {
 97         try {
 98             BufferedImage img = ImageIO.read(input);
 99             int w = img.getWidth(null);
100             int h = img.getHeight(null);
101             return new int[] { w, h };
102         } catch (IOException e) {
103             e.printStackTrace();
104             throw new Exception(e);
105         }
106     }
107 
108     /**
109      * 重调图片尺寸
110      * 
111      * @param srcFilePath
112      *            原图路径
113      * @param destFile
114      *            目标文件
115      * @param width
116      *            新的宽度,小于1则忽略,按原图比例缩放
117      * @param height
118      *            新的高度,小于1则忽略,按原图比例缩放
119      */
120     public static void resize(String srcFilePath, String destFile, int width, int height) throws Exception {
121         resize(srcFilePath, destFile, width, height, -1, -1);
122     }
123 
124     /**
125      * 重调图片尺寸
126      * 
127      * @param input
128      *            a {@link java.io.InputStream} object.
129      * @param output
130      *            a {@link java.io.OutputStream} object.
131      * @param width
132      *            a int.
133      * @param height
134      *            a int.
135      */
136     public static void resize(InputStream input, OutputStream output, int width, int height) throws Exception {
137         resize(input, output, width, height, -1, -1);
138     }
139 
140     /**
141      * 重调图片尺寸
142      * 
143      * @param input
144      *            a {@link java.io.InputStream} object.
145      * @param output
146      *            a {@link java.io.OutputStream} object.
147      * @param width
148      *            a int.
149      * @param height
150      *            a int.
151      * @param maxWidth
152      *            a int.
153      * @param maxHeight
154      *            a int.
155      */
156     public static void resize(InputStream input, OutputStream output,
157             int width, int height, int maxWidth, int maxHeight) throws Exception {
158 
159         if (width < 1 && height < 1 && maxWidth < 1 && maxHeight < 1) {
160             try {
161                 IOUtils.copy(input, output);
162             } catch (IOException e) {
163                 throw new Exception("resize error: ", e);
164             }
165         }
166         try {
167             BufferedImage img = ImageIO.read(input);
168             boolean hasNotAlpha = !img.getColorModel().hasAlpha();
169             double w = img.getWidth(null);
170             double h = img.getHeight(null);
171             int toWidth;
172             int toHeight;
173             double rate = w / h;
174 
175             if (width > 0 && height > 0) {
176                 rate = ((double) width) / ((double) height);
177                 toWidth = width;
178                 toHeight = height;
179             } else if (width > 0) {
180                 toWidth = width;
181                 toHeight = (int) (toWidth / rate);
182             } else if (height > 0) {
183                 toHeight = height;
184                 toWidth = (int) (toHeight * rate);
185             } else {
186                 toWidth = ((Number) w).intValue();
187                 toHeight = ((Number) h).intValue();
188             }
189 
190             if (maxWidth > 0 && toWidth > maxWidth) {
191                 toWidth = maxWidth;
192                 toHeight = (int) (toWidth / rate);
193             }
194             if (maxHeight > 0 && toHeight > maxHeight) {
195                 toHeight = maxHeight;
196                 toWidth = (int) (toHeight * rate);
197             }
198 
199             BufferedImage tag = new BufferedImage(toWidth, toHeight, hasNotAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB);
200 
201             // Image.SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢
202             tag.getGraphics().drawImage(img.getScaledInstance(toWidth, toHeight, Image.SCALE_SMOOTH), 0, 0, null);
203             ImageIO.write(tag, hasNotAlpha ? "jpg" : "png", output);
204         } catch (Exception e) {
205             e.printStackTrace();
206             throw new Exception(e);
207         } finally {
208             IOUtils.closeQuietly(input);
209             IOUtils.closeQuietly(output);
210         }
211 
212     }
213 
214     /**
215      * 重调图片尺寸
216      * 
217      * @param srcFile
218      *            原图路径
219      * @param destFile
220      *            目标文件
221      * @param width
222      *            新的宽度,小于1则忽略,按原图比例缩放
223      * @param height
224      *            新的高度,小于1则忽略,按原图比例缩放
225      * @param maxWidth
226      *            最大宽度,限制目标图片宽度,小于1则忽略此设置
227      * @param maxHeight
228      *            最大高度,限制目标图片高度,小于1则忽略此设置
229      */
230     public static void resize(String srcFile, String destFile, int width,
231             int height, int maxWidth, int maxHeight) throws Exception {
232         resize(new File(srcFile), new File(destFile), width, height, maxWidth, maxHeight);
233     }
234 
235     /**
236      * 重调图片尺寸
237      * 
238      * @param srcFile
239      *            原图路径
240      * @param destFile
241      *            目标文件
242      * @param width
243      *            新的宽度,小于1则忽略,按原图比例缩放
244      * @param height
245      *            新的高度,小于1则忽略,按原图比例缩放
246      */
247     public static void resize(File srcFile, File destFile, int width, int height) throws Exception {
248         resize(srcFile, destFile, width, height, -1, -1);
249     }
250 
251     /**
252      * 重调图片尺寸
253      * 
254      * @param srcFile
255      *            原图路径
256      * @param destFile
257      *            目标文件
258      * @param width
259      *            新的宽度,小于1则忽略,按原图比例缩放
260      * @param height
261      *            新的高度,小于1则忽略,按原图比例缩放
262      * @param maxWidth
263      *            最大宽度,限制目标图片宽度,小于1则忽略此设置
264      * @param maxHeight
265      *            最大高度,限制目标图片高度,小于1则忽略此设置
266      */
267     public static void resize(File srcFile, File destFile, int width,
268             int height, int maxWidth, int maxHeight) throws Exception {
269         if (destFile.exists()) {
270             destFile.delete();
271         } else {
272             FolderUtils.mkdirs(destFile.getParent());
273         }
274         InputStream input = null;
275         OutputStream output = null;
276         try {
277             input = new BufferedInputStream(new FileInputStream(srcFile));
278             output = new FileOutputStream(destFile);
279             resize(input, output, width, height, maxWidth, maxHeight);
280         } catch (FileNotFoundException e) {
281             e.printStackTrace();
282             throw new Exception(e);
283         } finally {
284             IOUtils.closeQuietly(input);
285             IOUtils.closeQuietly(output);
286         }
287     }
288 
289     /**
290      * 裁剪图片
291      * 
292      * @param source
293      *            a {@link java.lang.String} object.
294      * @param target
295      *            a {@link java.lang.String} object.
296      * @param x
297      *            a int.
298      * @param y
299      *            a int.
300      * @param w
301      *            a int.
302      * @param h
303      *            a int.
304      */
305     public static void crop(String source, String target, int x, int y, int w, int h) throws Exception {
306         crop(new File(source), new File(target), x, y, w, h);
307     }
308 
309     /**
310      * 裁剪图片
311      * 
312      * @param source
313      *            a {@link java.io.File} object.
314      * @param target
315      *            a {@link java.io.File} object.
316      * @param x
317      *            a int.
318      * @param y
319      *            a int.
320      * @param w
321      *            a int.
322      * @param h
323      *            a int.
324      */
325     public static void crop(File source, File target, int x, int y, int w, int h) throws Exception {
326         OutputStream output = null;
327         InputStream input = null;
328         String ext = FilenameUtils.getExtension(target.getName());
329         try {
330             input = new BufferedInputStream(new FileInputStream(source));
331             if (target.exists()) {
332                 target.delete();
333             } else {
334                 FolderUtils.mkdirs(target.getParent());
335             }
336             output = new BufferedOutputStream(new FileOutputStream(target));
337         } catch (IOException e) {
338             throw new Exception(e);
339         }
340         crop(input, output, x, y, w, h, StringUtils.equalsIgnoreCase("png", ext));
341     }
342 
343     /**
344      * 裁剪图片
345      * 
346      * @param x
347      *            a int.
348      * @param y
349      *            a int.
350      * @param w
351      *            a int.
352      * @param h
353      *            a int.
354      * @param input
355      *            a {@link java.io.InputStream} object.
356      * @param output
357      *            a {@link java.io.OutputStream} object.
358      * @param isPNG
359      *            a boolean.
360      */
361     public static void crop(InputStream input, OutputStream output, int x,
362             int y, int w, int h, boolean isPNG) throws Exception {
363         try {
364             BufferedImage srcImg = ImageIO.read(input);
365             int tmpWidth = srcImg.getWidth();
366             int tmpHeight = srcImg.getHeight();
367             int xx = Math.min(tmpWidth - 1, x);
368             int yy = Math.min(tmpHeight - 1, y);
369 
370             int ww = w;
371             if (xx + w > tmpWidth) {
372                 ww = Math.max(1, tmpWidth - xx);
373             }
374             int hh = h;
375             if (yy + h > tmpHeight) {
376                 hh = Math.max(1, tmpHeight - yy);
377             }
378 
379             BufferedImage dest = srcImg.getSubimage(xx, yy, ww, hh);
380 
381             BufferedImage tag = new BufferedImage(w, h, isPNG ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB);
382 
383             tag.getGraphics().drawImage(dest, 0, 0, null);
384             ImageIO.write(tag, isPNG ? "png" : "jpg", output);
385         } catch (Exception e) {
386             e.printStackTrace();
387             throw new Exception(e);
388         } finally {
389             IOUtils.closeQuietly(input);
390             IOUtils.closeQuietly(output);
391         }
392     }
393 
394     /**
395      * 压缩图片,PNG图片按JPG处理
396      * 
397      * @param input
398      *            a {@link java.io.InputStream} object.
399      * @param output
400      *            a {@link java.io.OutputStream} object.
401      * @param quality
402      *            图片质量0-1之间
403      */
404     public static final void optimize(InputStream input, OutputStream output, float quality) throws Exception {
405 
406         // create a BufferedImage as the result of decoding the supplied
407         // InputStream
408         BufferedImage image;
409         ImageOutputStream ios = null;
410         ImageWriter writer = null;
411         try {
412             image = ImageIO.read(input);
413 
414             // get all image writers for JPG format
415             Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpeg");
416 
417             if (!writers.hasNext())
418                 throw new IllegalStateException("No writers found");
419 
420             writer = (ImageWriter) writers.next();
421             ios = ImageIO.createImageOutputStream(output);
422 
423             writer.setOutput(ios);
424 
425             ImageWriteParam param = writer.getDefaultWriteParam();
426 
427             // optimize to a given quality
428             param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
429             param.setCompressionQuality(quality);
430 
431             // appends a complete image stream containing a single image and
432             // associated stream and image metadata and thumbnails to the output
433             writer.write(null, new IIOImage(image, null, null), param);
434         } catch (IOException e) {
435             e.printStackTrace();
436             throw new Exception(e);
437         } finally {
438             if (ios != null) {
439                 try {
440                     ios.close();
441                 } catch (IOException e) {
442                     e.printStackTrace();
443                     throw new Exception(e);
444                 }
445             }
446             writer.dispose();
447         }
448     }
449 
450     /**
451      * 压缩图片
452      * 
453      * @param source
454      *            a {@link java.lang.String} object.
455      * @param target
456      *            a {@link java.lang.String} object.
457      * @param quality
458      *            a float.
459      */
460     public static final void optimize(String source, String target, float quality) throws Exception {
461         File fromFile = new File(source);
462         File toFile = new File(target);
463         optimize(fromFile, toFile, quality);
464     }
465 
466     /**
467      * 压缩图片
468      * 
469      * @param source
470      *            a {@link java.io.File} object.
471      * @param target
472      *            a {@link java.io.File} object.
473      * @param quality
474      *            图片质量0-1之间
475      */
476     public static final void optimize(File source, File target, float quality) throws Exception {
477         if (target.exists()) {
478             target.delete();
479         } else {
480             FolderUtils.mkdirs(target.getParent());
481         }
482         InputStream is = null;
483         OutputStream os = null;
484         try {
485             is = new BufferedInputStream(new FileInputStream(source));
486             os = new BufferedOutputStream(new FileOutputStream(target));
487             optimize(is, os, quality);
488         } catch (FileNotFoundException e) {
489             throw new Exception(e);
490         } finally {
491             IOUtils.closeQuietly(is);
492             IOUtils.closeQuietly(os);
493         }
494     }
495 
496     /**
497      * 制作圆角
498      * 
499      * @param srcFile
500      *            原文件
501      * @param destFile
502      *            目标文件
503      * @param cornerRadius
504      *            角度
505      */
506     public static void makeRoundedCorner(File srcFile, File destFile, int cornerRadius) throws Exception {
507         InputStream in = null;
508         OutputStream out = null;
509 
510         try {
511             in = new BufferedInputStream(new FileInputStream(srcFile));
512             FolderUtils.mkdirs(destFile.getParentFile().getAbsolutePath());
513             out = new BufferedOutputStream(new FileOutputStream(destFile));
514             makeRoundedCorner(in, out, cornerRadius);
515         } catch (IOException e) {
516             e.printStackTrace();
517             throw new Exception(e);
518         } finally {
519             IOUtils.closeQuietly(out);
520             IOUtils.closeQuietly(in);
521         }
522 
523     }
524 
525     /**
526      * 制作圆角
527      * 
528      * @param srcFile
529      *            原文件
530      * @param destFile
531      *            目标文件
532      * @param cornerRadius
533      *            角度
534      */
535     public static void makeRoundedCorner(String srcFile, String destFile, int cornerRadius) throws Exception {
536         makeRoundedCorner(new File(srcFile), new File(destFile), cornerRadius);
537     }
538 
539     /**
540      * 制作圆角
541      * 
542      * @param inputStream
543      *            原图输入流
544      * @param outputStream
545      *            目标输出流
546      * @param radius
547      *            角度
548      */
549     public static void makeRoundedCorner(final InputStream inputStream,
550             final OutputStream outputStream, final int radius) throws Exception {
551         BufferedImage sourceImage = null;
552         BufferedImage targetImage = null;
553         try {
554             sourceImage = ImageIO.read(inputStream);
555             int w = sourceImage.getWidth();
556             int h = sourceImage.getHeight();
557             System.out.println(w);
558 
559             int cornerRadius = radius < 1 ? w / 4 : radius;
560 
561             targetImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
562 
563             Graphics2D g2 = targetImage.createGraphics();
564 
565             // This is what we want, but it only does hard-clipping, i.e.
566             // aliasing
567             // g2.setClip(new RoundRectangle2D ...)
568 
569             // so instead fake soft-clipping by first drawing the desired clip
570             // shape
571             // in fully opaque white with antialiasing enabled...
572             g2.setComposite(AlphaComposite.Src);
573             g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
574             g2.setColor(Color.WHITE);
575             g2.fill(new RoundRectangle2D.Float(0, 0, w, h, cornerRadius, cornerRadius));
576 
577             // ... then compositing the image on top,
578             // using the white shape from above as alpha source
579             g2.setComposite(AlphaComposite.SrcAtop);
580             g2.drawImage(sourceImage, 0, 0, null);
581             g2.dispose();
582             ImageIO.write(targetImage, "png", outputStream);
583         } catch (IOException e) {
584             e.printStackTrace();
585             throw new Exception(e);
586         }
587     }
588 
589 }

 

posted @ 2016-02-19 12:32  小周JAVA技术分享  阅读(3529)  评论(0编辑  收藏  举报