图片处理工具类 - ImageUtils.java
纯JAVA实现的图片处理工具类,提供图片的裁剪、压缩、获取尺寸、制作圆角等方法。
源码如下:(点击下载 -ImageUtils.java 、FolderUtils.java 、commons-io-2.4.jar、commons-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 }
欢迎访问 JAVA技术分享 www.2b2b92b.com