圖片工具類,完成圖片的截取和任意縮放: java
package com.common.util; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.WritableRaster; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import javax.imageio.ImageIO; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.swt.graphics.Rectangle; import com.gif4j.GifDecoder; import com.gif4j.GifEncoder; import com.gif4j.GifImage; import com.gif4j.GifTransformer; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; /** 圖片工具類,完成圖片的截取 * * @author Beau Virgill */ public class IamgesResize { private static Log log = LogFactory.getLog(IamgesResize.class); BufferedImage bufImage; // 原始圖片 int width; // 縮放的寬度 int height; // 縮放的高度 public IamgesResize() { // TODO Auto-generated constructor stub } public IamgesResize(String srcPath, int width, int height) { this.width = width; this.height = height; try { this.bufImage = ImageIO.read(new File(srcPath)); } catch (Exception e) { e.printStackTrace(); } } /** 實現圖像的等比縮放和縮放後的截取,若是高度的值和寬度同樣,則縮放按設置的值縮放 (只控制寬度的大小,高度的值設置不生效(只有高度的值和寬度的同樣才生效), 高度自動按比例縮放;若是縮放的圖片小於你設置的值則保存原圖大小) * * @param inFilePath * 要縮放圖片文件的路徑 * @param outFilePath * 縮放後保存圖片輸出的路徑 * @param width * 要截取寬度 * @param hight * 要截取的高度 * @throws Exception */ public static void zoomOutImage(String inFilePath, String outFilePath, int width, int hight, boolean smooth) throws Exception { int maxHight = 500; // 設置最大的圖片高度; File file = new File(inFilePath); InputStream in = new FileInputStream(file); File saveFile = new File(outFilePath); BufferedImage srcImage = ImageIO.read(in); String gif = inFilePath.substring(inFilePath.lastIndexOf(".") + 1, inFilePath.length()); if ((gif.equals("gif") || gif.equals("GIF")) && smooth == true) // gif動態圖片的處理 { IamgesResize.getGifImage(inFilePath, outFilePath, width, hight, true); } else { // 若是寬度和高度同樣 或者圖片的規格爲 images_120 時不按等比縮放,若是須要等比縮放, 則將下面的 if 語句註釋便可 if (width != hight && !outFilePath.contains("images_120")) { double sx = (double) width / srcImage.getWidth(); hight = (int) (srcImage.getHeight() * sx); } log.info("原理圖片路徑------>" + inFilePath); log.info("保存圖片新路徑------>" + saveFile); if (width > 0 || hight > 0) { // 原圖的大小 int sw = srcImage.getWidth(); int sh = srcImage.getHeight(); log.info("原圖寬=" + sw); log.info("原圖高=" + sh); // 若是原圖像的大小小於要縮放的圖像大小,直接將要縮放的圖像複製過去 if (sw > width && sh > hight) { srcImage = rize(srcImage, width, hight); } else { log.info("原圖片的大小小於要縮放的大小,不須要縮小"); String fileName = saveFile.getName(); String formatName = fileName.substring(fileName.lastIndexOf('.') + 1); ImageIO.write(srcImage, formatName, saveFile); return; } } // 縮放後的圖像的寬和高 int w = srcImage.getWidth(); int h = srcImage.getHeight(); log.info("縮小圖片寬度= " + w); log.info("縮小圖片高度= " + h); // 若是縮放後的圖像和要求的圖像寬度同樣,就對縮放的圖像的高度進行截取 if (w == width) { // 計算 X軸座標 int x = 0; // 若是圖片超過指定高度則截取必定的高度 if (h >= maxHight && width != 600) // 圖片爲600 的不須要截取高度 { int y = h / 2 - hight / 2; saveSubImage(srcImage, new Rectangle(x, y, width, maxHight), saveFile); } else { int y = h / 2 - hight / 2; saveSubImage(srcImage, new Rectangle(x, y, width, hight), saveFile); } } // 不然若是是縮放後的圖像的高度和要求的圖像高度同樣,就對縮放後的圖像的寬度進行截取 else if (h == hight) { // 計算X軸座標 int x = w / 2 - width / 2; int y = 0; saveSubImage(srcImage, new Rectangle(x, y, width, hight), saveFile); } in.close(); } } /** @param srcPath * 圖片的絕對路徑 * @param width * 圖片要縮放的寬度 * @param height * 圖片要縮放的高度 * @param rizeType * 圖片要縮放的類型(1:寬度固定,高度自動 2:按寬度和高度比例縮小) * @return */ public static BufferedImage rize(BufferedImage srcBufImage, int width, int height) { BufferedImage bufTarget = null; int type = srcBufImage.getType(); double sx = (double) width / srcBufImage.getWidth(); double sy = (double) height / srcBufImage.getHeight(); log.info("w=" + sx); log.info("h=" + sx); if (type == BufferedImage.TYPE_CUSTOM) { ColorModel cm = srcBufImage.getColorModel(); WritableRaster raster = cm.createCompatibleWritableRaster(width, height); boolean alphaPremultiplied = cm.isAlphaPremultiplied(); bufTarget = new BufferedImage(cm, raster, alphaPremultiplied, null); } else { bufTarget = new BufferedImage(width, height, type); } Graphics2D g = bufTarget.createGraphics(); g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g.drawRenderedImage(srcBufImage, AffineTransform.getScaleInstance(sx, sy)); g.dispose(); return bufTarget; } /** 實現縮放後的截圖 * * @param image * 縮放後的圖像 * @param subImageBounds * 要截取的子圖的範圍 * @param subImageFile * 要保存的文件 * @throws IOException */ private static void saveSubImage(BufferedImage image, Rectangle subImageBounds, File subImageFile) throws IOException { if (subImageBounds.x < 0 || subImageBounds.y < 0 || subImageBounds.width - subImageBounds.x > image.getWidth() || subImageBounds.height - subImageBounds.y > image.getHeight()) { log.info("Bad subimage bounds"); return; } BufferedImage subImage = image.getSubimage(subImageBounds.x, subImageBounds.y, subImageBounds.width, subImageBounds.height); String fileName = subImageFile.getName(); String formatName = fileName.substring(fileName.lastIndexOf('.') + 1); ImageIO.write(subImage, formatName, subImageFile); } /** 針對書籤截屏的等比縮放(等比縮放,不失真) * * @param src * 源圖片文件完整路徑 * @param dist * 目標圖片文件完整路徑 * @param width * 縮放的寬度 * @param heightw * 縮放的高度 */ public static void createThumbnail(String src, String dist, float width, float height) { try { File srcfile = new File(src); if (!srcfile.exists()) { log.error("文件不存在"); return; } BufferedImage image = ImageIO.read(srcfile); // 得到縮放的比例 double ratio = 1.0; // 判斷若是高、寬都不大於設定值,則不處理 if (image.getHeight() > height || image.getWidth() > width) { if (image.getHeight() > image.getWidth()) { ratio = height / image.getHeight(); } else { ratio = width / image.getWidth(); } } // 計算新的圖面寬度和高度 int newWidth = (int) (image.getWidth() * ratio); int newHeight = (int) (image.getHeight() * ratio); BufferedImage bfImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB); bfImage.getGraphics().drawImage(image.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH), 0, 0, null); FileOutputStream os = new FileOutputStream(dist); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os); encoder.encode(bfImage); os.close(); log.info("建立縮略圖成功"); } catch (Exception e) { log.error("建立縮略圖發生異常" + e.getMessage()); } } /** 實現圖像的等比縮放和縮放後的截取,若是高度的值和寬度同樣,則縮放按設置的值縮放 (只控制寬度的大小,高度的值設置不生效(只有高度的值和寬度的同樣才生效), 高度自動按比例縮放;若是縮放的圖片小於你設置的值則保存原圖大小) * 若是要縮放的寬度和高度相等則不按比例縮放;直接縮小圖片 * * @param filepath * 要縮放圖片文件的路徑 * @param saveFilePath * 縮放後保存圖片輸出的路徑 * @param imgWidth * 要縮放的寬度 * @param imHeight * 要縮放的高度 * @return * @throws Exception */ public static boolean readPicfile(String filepath, String saveFilePath, int imgWidth, int imHeight) throws Exception { File file = new File(filepath); if (file.isDirectory()) { // 若是path表示的是不是文件夾,是返回true log.info("文件夾"); String[] filelist = file.list(); log.info("總圖片個數=" + filelist.length); int count = 0; for (int i = 0; i < filelist.length; i++) { File readfile = new File(filepath + filelist[i]); if (!readfile.isDirectory()) { log.info("absolutepath=" + readfile.getAbsolutePath()); log.info("imgName=" + readfile.getName()); String imgfuffix = readfile.getName().substring(readfile.getName().lastIndexOf(".") + 1, readfile.getName().length()); // 獲取文件的後綴 // 是圖片類型的才執行縮放 if (isFromImgUrl(imgfuffix)) { count++; IamgesResize.zoomOutImage(filepath + readfile.getName(), saveFilePath + readfile.getName(), imgWidth, imHeight, true); IamgesResize.createThumbnail(filepath + readfile.getName(), saveFilePath + readfile.getName(), imgWidth, imHeight); } } } } return true; } /** gif圖片縮放有動態效果 * * @param srcImg * 原始文件 * @param destImg * 要保存的文件 * @param width * 寬度 * @param height * 高度 * @param smooth * @throws Exception */ public static void getGifImage(String srcImg, String destImg, int width, int hight, boolean smooth) throws Exception { try { File file = new File(srcImg); File saveFile = new File(destImg); InputStream in = new FileInputStream(srcImg); BufferedImage srcImage = ImageIO.read(in); GifImage gifImage = GifDecoder.decode(file);// 建立一個GifImage對象. if (width > 0 || hight > 0) { // 原圖的大小 int sw = srcImage.getWidth(); int sh = srcImage.getHeight(); if (width == hight) { } else if (sw > width) { double sx = (double) width / srcImage.getWidth(); hight = (int) (srcImage.getHeight() * sx); } else { width = sw; hight = sh; } } // 1.縮放從新更改大小. GifImage resizeIMG = GifTransformer.resize(gifImage, width, hight, true); // 2.剪切圖片演示. // Rectangle rect = new Rectangle(0,0,200,200); // GifImage cropIMG = GifTransformer.crop(gifImage, rect); // 3.按比例縮放 // GifImage resizeIMG = GifTransformer.scale(gifImage, 1.0, 1.0,true);//參數須要double型 // 4.其餘的方法.還有不少,好比水平翻轉,垂直翻轉 等等.都是GifTransformer類裏面的. GifEncoder.encode(resizeIMG, saveFile); } catch (IOException e) { e.printStackTrace(); log.debug("保存失敗(該圖爲修改過得gif圖片),從新保存一次。"); IamgesResize.zoomOutImage(srcImg, destImg, width, hight, false); } } /** 判斷網址是否是圖片類型。 * * @param fromUrl * @return */ public static boolean isFromImgUrl(String imgfuffix) { boolean isImage = false; // 支持的圖片後綴。 String[] imgSuffixs = { "jpg", "JPG", "jpeg", "JPEG", "gif", "GIF", "png", "PNG", "bmp", "BMP" }; for (int i = 0; i < imgSuffixs.length; i++) { if (imgfuffix.equals(imgSuffixs[i])) { isImage = true; break; } } return isImage; } }