java生成圖片縮圖
阿新 • • 發佈:2019-02-13
當圖片很大的時候,要生成預覽圖來提高網站響應速率,採用java的image相關類來生成縮圖
package com.liuc.core; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import com.liuc.config.ImageSizeConfig; import com.liuc.util.UUIDUtil; /** * * @brief ThumbnailUtil.java 生成縮圖 */ public class ThumbnailUtil { /** * 寬度 */ private int width; /** * 高度 */ private int height; private int scaleWidth; double support = (double) 3.0; double PI = (double) 3.14159265358978; double[] contrib; double[] normContrib; double[] tmpContrib; int startContrib, stopContrib; int nDots; int nHalfDots; /** *//** * Start: Use Lanczos filter to replace the original algorithm for image * scaling. Lanczos improves quality of the scaled image modify by :blade */ public static void main(String[] args) { ThumbnailUtil is = new ThumbnailUtil(); try { is.compressImageAsJpg(new File("D:/123/1.jpg"), new File("D:/123/1111.jpg"), 765, 129); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public File compressImgByAssignMinBoundLength(File inFile, ImageSizeConfig pc) throws Exception{ try { Image img = ImageIO.read(inFile); int width = img.getWidth(null); int height = img.getHeight(null); int OutputWidth = pc.getWidth(); int OutputHeight = pc.getHeight(); int new_w,new_h; if (height <= OutputWidth && width <= OutputHeight) {// 不壓縮 new_w = width; new_h = height; } else if (height > width) {// 已寬為準 new_w = OutputWidth; new_h = (int) (new_w / ((double) width / (double) height)); } else {// 已高為準 new_h = OutputHeight; new_w = (int) ((new_h * (double) width / (double) height)); } String fileName = UUIDUtil.getUUID() + pc.getExt(); File tmpFile = new File("D:/123", fileName); compressImageAsJpg(inFile, tmpFile, new_w, new_h); return tmpFile; } catch (Exception e) { throw new Exception("compress img error.", e); } } /** * 壓縮圖片 * @param fromFileStr * @param saveToFileStr * @param formatWideth * @param formatHeight * @throws Exception */ public void compressImageAsJpg(File fromFile, File saveToFile, int formatWideth, int formatHeight) throws Exception{ try { saveImageAsJpg(fromFile, saveToFile, formatWideth, formatHeight); } catch (Exception e) { throw new Exception("compress img error.", e); } } // fromFileStr原圖片地址,saveToFileStr生成縮圖地址,formatWideth生成圖片寬度,formatHeight高度 public void saveImageAsJpg(File inputFile, File saveToFile, int formatWideth, int formatHeight) throws Exception { BufferedImage srcImage; File saveFile = saveToFile; File fromFile = inputFile; srcImage = javax.imageio.ImageIO.read(fromFile); // construct image int imageWideth = srcImage.getWidth(null); int imageHeight = srcImage.getHeight(null); int changeToWideth = 0; int changeToHeight = 0; if (imageWideth > 0 && imageHeight > 0) { // flag=true; if (imageWideth / imageHeight >= formatWideth / formatHeight) { if (imageWideth > formatWideth) { changeToWideth = formatWideth; changeToHeight = (imageHeight * formatWideth) / imageWideth; } else { changeToWideth = imageWideth; changeToHeight = imageHeight; } } else { if (imageHeight > formatHeight) { changeToHeight = formatHeight; changeToWideth = (imageWideth * formatHeight) / imageHeight; } else { changeToWideth = imageWideth; changeToHeight = imageHeight; } } } srcImage = imageZoomOut(srcImage, changeToWideth, changeToHeight); ImageIO.write(srcImage, "JPEG", saveFile); } public BufferedImage imageZoomOut(BufferedImage srcBufferImage, int w, int h) { width = srcBufferImage.getWidth(); height = srcBufferImage.getHeight(); scaleWidth = w; if (DetermineResultSize(w, h) == 1) { return srcBufferImage; } CalContrib(); BufferedImage pbOut = HorizontalFiltering(srcBufferImage, w); BufferedImage pbFinalOut = VerticalFiltering(pbOut, h); return pbFinalOut; } /** * 決定影象尺寸 */ private int DetermineResultSize(int w, int h) { double scaleH, scaleV; scaleH = (double) w / (double) width; scaleV = (double) h / (double) height; // 需要判斷一下scaleH,scaleV,不做放大操作 if (scaleH >= 1.0 && scaleV >= 1.0) { return 1; } return 0; } // end of DetermineResultSize() private double Lanczos(int i, int inWidth, int outWidth, double Support) { double x; x = (double) i * (double) outWidth / (double) inWidth; return Math.sin(x * PI) / (x * PI) * Math.sin(x * PI / Support) / (x * PI / Support); } private void CalContrib() { nHalfDots = (int) ((double) width * support / (double) scaleWidth); nDots = nHalfDots * 2 + 1; try { contrib = new double[nDots]; normContrib = new double[nDots]; tmpContrib = new double[nDots]; } catch (Exception e) { System.out.println("init contrib,normContrib,tmpContrib" + e); } int center = nHalfDots; contrib[center] = 1.0; double weight = 0.0; int i = 0; for (i = 1; i <= center; i++) { contrib[center + i] = Lanczos(i, width, scaleWidth, support); weight += contrib[center + i]; } for (i = center - 1; i >= 0; i--) { contrib[i] = contrib[center * 2 - i]; } weight = weight * 2 + 1.0; for (i = 0; i <= center; i++) { normContrib[i] = contrib[i] / weight; } for (i = center + 1; i < nDots; i++) { normContrib[i] = normContrib[center * 2 - i]; } } // end of CalContrib() // 處理邊緣 private void CalTempContrib(int start, int stop) { double weight = 0; int i = 0; for (i = start; i <= stop; i++) { weight += contrib[i]; } for (i = start; i <= stop; i++) { tmpContrib[i] = contrib[i] / weight; } } // end of CalTempContrib() private int GetRedValue(int rgbValue) { int temp = rgbValue & 0x00ff0000; return temp >> 16; } private int GetGreenValue(int rgbValue) { int temp = rgbValue & 0x0000ff00; return temp >> 8; } private int GetBlueValue(int rgbValue) { return rgbValue & 0x000000ff; } private int ComRGB(int redValue, int greenValue, int blueValue) { return (redValue << 16) + (greenValue << 8) + blueValue; } // 行水平濾波 private int HorizontalFilter(BufferedImage bufImg, int startX, int stopX, int start, int stop, int y, double[] pContrib) { double valueRed = 0.0; double valueGreen = 0.0; double valueBlue = 0.0; int valueRGB = 0; int i, j; for (i = startX, j = start; i <= stopX; i++, j++) { valueRGB = bufImg.getRGB(i, y); valueRed += GetRedValue(valueRGB) * pContrib[j]; valueGreen += GetGreenValue(valueRGB) * pContrib[j]; valueBlue += GetBlueValue(valueRGB) * pContrib[j]; } valueRGB = ComRGB(Clip((int) valueRed), Clip((int) valueGreen), Clip((int) valueBlue)); return valueRGB; } // end of HorizontalFilter() // 圖片水平濾波 private BufferedImage HorizontalFiltering(BufferedImage bufImage, int iOutW) { int dwInW = bufImage.getWidth(); int dwInH = bufImage.getHeight(); int value = 0; BufferedImage pbOut = new BufferedImage(iOutW, dwInH, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < iOutW; x++) { int startX; int start; int X = (int) (((double) x) * ((double) dwInW) / ((double) iOutW) + 0.5); int y = 0; startX = X - nHalfDots; if (startX < 0) { startX = 0; start = nHalfDots - X; } else { start = 0; } int stop; int stopX = X + nHalfDots; if (stopX > (dwInW - 1)) { stopX = dwInW - 1; stop = nHalfDots + (dwInW - 1 - X); } else { stop = nHalfDots * 2; } if (start > 0 || stop < nDots - 1) { CalTempContrib(start, stop); for (y = 0; y < dwInH; y++) { value = HorizontalFilter(bufImage, startX, stopX, start, stop, y, tmpContrib); pbOut.setRGB(x, y, value); } } else { for (y = 0; y < dwInH; y++) { value = HorizontalFilter(bufImage, startX, stopX, start, stop, y, normContrib); pbOut.setRGB(x, y, value); } } } return pbOut; } // end of HorizontalFiltering() private int VerticalFilter(BufferedImage pbInImage, int startY, int stopY, int start, int stop, int x, double[] pContrib) { double valueRed = 0.0; double valueGreen = 0.0; double valueBlue = 0.0; int valueRGB = 0; int i, j; for (i = startY, j = start; i <= stopY; i++, j++) { valueRGB = pbInImage.getRGB(x, i); valueRed += GetRedValue(valueRGB) * pContrib[j]; valueGreen += GetGreenValue(valueRGB) * pContrib[j]; valueBlue += GetBlueValue(valueRGB) * pContrib[j]; // System.out.println(valueRed+"->"+Clip((int)valueRed)+"<-"); // // System.out.println(valueGreen+"->"+Clip((int)valueGreen)+"<-"); // System.out.println(valueBlue+"->"+Clip((int)valueBlue)+"<-"+"-->"); } valueRGB = ComRGB(Clip((int) valueRed), Clip((int) valueGreen), Clip((int) valueBlue)); // System.out.println(valueRGB); return valueRGB; } // end of VerticalFilter() private BufferedImage VerticalFiltering(BufferedImage pbImage, int iOutH) { int iW = pbImage.getWidth(); int iH = pbImage.getHeight(); int value = 0; BufferedImage pbOut = new BufferedImage(iW, iOutH, BufferedImage.TYPE_INT_RGB); for (int y = 0; y < iOutH; y++) { int startY; int start; int Y = (int) (((double) y) * ((double) iH) / ((double) iOutH) + 0.5); startY = Y - nHalfDots; if (startY < 0) { startY = 0; start = nHalfDots - Y; } else { start = 0; } int stop; int stopY = Y + nHalfDots; if (stopY > (int) (iH - 1)) { stopY = iH - 1; stop = nHalfDots + (iH - 1 - Y); } else { stop = nHalfDots * 2; } if (start > 0 || stop < nDots - 1) { CalTempContrib(start, stop); for (int x = 0; x < iW; x++) { value = VerticalFilter(pbImage, startY, stopY, start, stop, x, tmpContrib); pbOut.setRGB(x, y, value); } } else { for (int x = 0; x < iW; x++) { value = VerticalFilter(pbImage, startY, stopY, start, stop, x, normContrib); pbOut.setRGB(x, y, value); } } } return pbOut; } // end of VerticalFiltering() int Clip(int x) { if (x < 0) return 0; if (x > 255) return 255; return x; } }
package com.liuc.util; import java.util.UUID; public class UUIDUtil { public static String getUUID() { UUID uuid = UUID.randomUUID(); String str = uuid.toString(); // 去掉"-"符號 String temp = str.substring(0, 8) + str.substring(9, 13) + str.substring(14, 18) + str.substring(19, 23) + str.substring(24); return str+","+temp; } }
package com.liuc.config;
public class ImageSizeConfig {
public int getWidth() {
return 320;
}
public int getHeight() {
return 240;
}
public String getExt() {
return ".jpg";
}
}