java图片生成等比例图片
最近在倒弄个一个网站,www.thinkdee.com 还在做,有一个上传图片LOGO需求,当然用户上传的图片不可能是原样输出的,这里要用等比例处理一下,不多说,附上代码:
1 package com.thinkdee.util; 2 3 4 import java.awt.image.BufferedImage; 5 import java.io.File; 6 7 import javax.imageio.ImageIO; 8 9 public class ScaleImage { 10 11 public ScaleImage() { 12 support = 3D; 13 PI = 3.1415926535897798D; 14 } 15 16 17 /** 18 * 19 * <b>Summary: </b> 20 * saveImageAsJpg(生成等比例图片) 21 * @param fromFileStr 22 * @param saveToFileStr 23 * @param formatWideth 24 * @param formatHeight 25 * @throws Exception 26 */ 27 public void saveImageAsJpg(String fromFileStr, String saveToFileStr, 28 int formatWideth, int formatHeight) throws Exception { 29 File saveFile = new File(saveToFileStr); 30 File fromFile = new File(fromFileStr); 31 BufferedImage srcImage = ImageIO.read(fromFile); 32 int imageWideth = srcImage.getWidth(null); 33 int imageHeight = srcImage.getHeight(null); 34 int changeToWideth = 0; 35 int changeToHeight = 0; 36 if (imageWideth > 0 && imageHeight > 0) 37 if (imageWideth / imageHeight >= formatWideth / formatHeight) { 38 if (imageWideth > formatWideth) { 39 changeToWideth = formatWideth; 40 changeToHeight = (imageHeight * formatWideth) / imageWideth; 41 } else { 42 changeToWideth = imageWideth; 43 changeToHeight = imageHeight; 44 } 45 } else if (imageHeight > formatHeight) { 46 changeToHeight = formatHeight; 47 changeToWideth = (imageWideth * formatHeight) / imageHeight; 48 } else { 49 changeToWideth = imageWideth; 50 changeToHeight = imageHeight; 51 } 52 srcImage = imageZoomOut(srcImage, changeToWideth, changeToHeight); 53 ImageIO.write(srcImage, "JPEG", saveFile); 54 } 55 56 public BufferedImage imageZoomOut(BufferedImage srcBufferImage, int w, int h) { 57 width = srcBufferImage.getWidth(); 58 height = srcBufferImage.getHeight(); 59 scaleWidth = w; 60 if (DetermineResultSize(w, h) == 1) { 61 return srcBufferImage; 62 } else { 63 CalContrib(); 64 BufferedImage pbOut = HorizontalFiltering(srcBufferImage, w); 65 BufferedImage pbFinalOut = VerticalFiltering(pbOut, h); 66 return pbFinalOut; 67 } 68 } 69 70 private int DetermineResultSize(int w, int h) { 71 double scaleH = (double) w / (double) width; 72 double scaleV = (double) h / (double) height; 73 return scaleH < 1.0D || scaleV < 1.0D ? 0 : 1; 74 } 75 76 private double Lanczos(int i, int inWidth, int outWidth, double Support) { 77 double x = ((double) i * (double) outWidth) / (double) inWidth; 78 return ((Math.sin(x * PI) / (x * PI)) * Math.sin((x * PI) / Support)) 79 / ((x * PI) / Support); 80 } 81 82 private void CalContrib() { 83 nHalfDots = (int) (((double) width * support) / (double) scaleWidth); 84 nDots = nHalfDots * 2 + 1; 85 try { 86 contrib = new double[nDots]; 87 normContrib = new double[nDots]; 88 tmpContrib = new double[nDots]; 89 } catch (Exception e) { 90 System.out.println("init contrib,normContrib,tmpContrib" + e); 91 } 92 int center = nHalfDots; 93 contrib[center] = 1.0D; 94 double weight = 0.0D; 95 int i = 0; 96 for (i = 1; i <= center; i++) { 97 contrib[center + i] = Lanczos(i, width, scaleWidth, support); 98 weight += contrib[center + i]; 99 } 100 101 for (i = center - 1; i >= 0; i--) 102 contrib[i] = contrib[center * 2 - i]; 103 104 weight = weight * 2D + 1.0D; 105 for (i = 0; i <= center; i++) 106 normContrib[i] = contrib[i] / weight; 107 108 for (i = center + 1; i < nDots; i++) 109 normContrib[i] = normContrib[center * 2 - i]; 110 111 } 112 113 private void CalTempContrib(int start, int stop) { 114 double weight = 0.0D; 115 int i = 0; 116 for (i = start; i <= stop; i++) 117 weight += contrib[i]; 118 119 for (i = start; i <= stop; i++) 120 tmpContrib[i] = contrib[i] / weight; 121 122 } 123 124 private int GetRedValue(int rgbValue) { 125 int temp = rgbValue & 0xff0000; 126 return temp >> 16; 127 } 128 129 private int GetGreenValue(int rgbValue) { 130 int temp = rgbValue & 0xff00; 131 return temp >> 8; 132 } 133 134 private int GetBlueValue(int rgbValue) { 135 return rgbValue & 0xff; 136 } 137 138 private int ComRGB(int redValue, int greenValue, int blueValue) { 139 return (redValue << 16) + (greenValue << 8) + blueValue; 140 } 141 142 private int HorizontalFilter(BufferedImage bufImg, int startX, int stopX, 143 int start, int stop, int y, double pContrib[]) { 144 double valueRed = 0.0D; 145 double valueGreen = 0.0D; 146 double valueBlue = 0.0D; 147 int valueRGB = 0; 148 int i = startX; 149 for (int j = start; i <= stopX; j++) { 150 valueRGB = bufImg.getRGB(i, y); 151 valueRed += (double) GetRedValue(valueRGB) * pContrib[j]; 152 valueGreen += (double) GetGreenValue(valueRGB) * pContrib[j]; 153 valueBlue += (double) GetBlueValue(valueRGB) * pContrib[j]; 154 i++; 155 } 156 157 valueRGB = ComRGB(Clip((int) valueRed), Clip((int) valueGreen), 158 Clip((int) valueBlue)); 159 return valueRGB; 160 } 161 162 private BufferedImage HorizontalFiltering(BufferedImage bufImage, int iOutW) { 163 int dwInW = bufImage.getWidth(); 164 int dwInH = bufImage.getHeight(); 165 int value = 0; 166 BufferedImage pbOut = new BufferedImage(iOutW, dwInH, 1); 167 for (int x = 0; x < iOutW; x++) { 168 int X = (int) (((double) x * (double) dwInW) / (double) iOutW + 0.5D); 169 int y = 0; 170 int startX = X - nHalfDots; 171 int start; 172 if (startX < 0) { 173 startX = 0; 174 start = nHalfDots - X; 175 } else { 176 start = 0; 177 } 178 int stopX = X + nHalfDots; 179 int stop; 180 if (stopX > dwInW - 1) { 181 stopX = dwInW - 1; 182 stop = nHalfDots + (dwInW - 1 - X); 183 } else { 184 stop = nHalfDots * 2; 185 } 186 if (start > 0 || stop < nDots - 1) { 187 CalTempContrib(start, stop); 188 for (y = 0; y < dwInH; y++) { 189 value = HorizontalFilter(bufImage, startX, stopX, start, 190 stop, y, tmpContrib); 191 pbOut.setRGB(x, y, value); 192 } 193 194 } else { 195 for (y = 0; y < dwInH; y++) { 196 value = HorizontalFilter(bufImage, startX, stopX, start, 197 stop, y, normContrib); 198 pbOut.setRGB(x, y, value); 199 } 200 201 } 202 } 203 204 return pbOut; 205 } 206 207 private int VerticalFilter(BufferedImage pbInImage, int startY, int stopY, 208 int start, int stop, int x, double pContrib[]) { 209 double valueRed = 0.0D; 210 double valueGreen = 0.0D; 211 double valueBlue = 0.0D; 212 int valueRGB = 0; 213 int i = startY; 214 for (int j = start; i <= stopY; j++) { 215 valueRGB = pbInImage.getRGB(x, i); 216 valueRed += (double) GetRedValue(valueRGB) * pContrib[j]; 217 valueGreen += (double) GetGreenValue(valueRGB) * pContrib[j]; 218 valueBlue += (double) GetBlueValue(valueRGB) * pContrib[j]; 219 i++; 220 } 221 222 valueRGB = ComRGB(Clip((int) valueRed), Clip((int) valueGreen), 223 Clip((int) valueBlue)); 224 return valueRGB; 225 } 226 227 private BufferedImage VerticalFiltering(BufferedImage pbImage, int iOutH) { 228 int iW = pbImage.getWidth(); 229 int iH = pbImage.getHeight(); 230 int value = 0; 231 BufferedImage pbOut = new BufferedImage(iW, iOutH, 1); 232 for (int y = 0; y < iOutH; y++) { 233 int Y = (int) (((double) y * (double) iH) / (double) iOutH + 0.5D); 234 int startY = Y - nHalfDots; 235 int start; 236 if (startY < 0) { 237 startY = 0; 238 start = nHalfDots - Y; 239 } else { 240 start = 0; 241 } 242 int stopY = Y + nHalfDots; 243 int stop; 244 if (stopY > iH - 1) { 245 stopY = iH - 1; 246 stop = nHalfDots + (iH - 1 - Y); 247 } else { 248 stop = nHalfDots * 2; 249 } 250 if (start > 0 || stop < nDots - 1) { 251 CalTempContrib(start, stop); 252 for (int x = 0; x < iW; x++) { 253 value = VerticalFilter(pbImage, startY, stopY, start, stop, 254 x, tmpContrib); 255 pbOut.setRGB(x, y, value); 256 } 257 258 } else { 259 for (int x = 0; x < iW; x++) { 260 value = VerticalFilter(pbImage, startY, stopY, start, stop, 261 x, normContrib); 262 pbOut.setRGB(x, y, value); 263 } 264 265 } 266 } 267 268 return pbOut; 269 } 270 271 int Clip(int x) { 272 if (x < 0) 273 return 0; 274 if (x > 255) 275 return 255; 276 else 277 return x; 278 } 279 280 private int width; 281 private int height; 282 private int scaleWidth; 283 double support; 284 double PI; 285 double contrib[]; 286 double normContrib[]; 287 double tmpContrib[]; 288 int startContrib; 289 int stopContrib; 290 int nDots; 291 int nHalfDots; 292 }