江苏520

江苏520

常用链接

统计

最新评论

JAVA生成高品质缩略图的代码与下载

import java.awt.image.BufferedImage;

public class ImageScale {

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;

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);

} // end of Lanczos()

//
// Assumption: same horizontal and vertical scaling factor
//
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;
}

public static void main(String[] args) {
}
}
}


-----------------------------------------------------------------------
public BufferedImage imageZoomOut(BufferedImage srcBufferImage, int w, int h)
我将这个方法改成了
public BufferedImage imageZoomOut(BufferedImage srcBufferImage, float w, float h)
为了方便同比例缩放,将w, h改为flaot型作为缩放比率,其他地方作相应的改动。

如果是在网页上显示的话,需要建一个Servlet,代码如下:
package servlet;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ImageScale;

public class ImageServlet extends HttpServlet {

  private static final long serialVersionUID = 1L;

  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }

  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    response.setHeader("Cache-Control", "no-store");
    response.setHeader("Pragma", "no-cache");
    response.setDateHeader("Expires", 0);
    response.setContentType("image/jpeg");
    
    // 图片放在当前应用的images目录下 如http://www.feng123.com 下的文件目录。
    String path = getServletContext().getRealPath("images/2.jpg");    
    BufferedImage image1 = ImageIO.read(new File(path));    
    
    if(request.getParameter("x") == null) {
      ImageIO.write(image1, "jpeg", response.getOutputStream());
    }else {
      float w = Float.parseFloat(request.getParameter("x"));
      float h;
      if(request.getParameter("y") == null) {
        h = w;
      }else{
        h = Float.parseFloat(request.getParameter("y"));
      }      
      ImageScale is = new ImageScale();
      BufferedImage image2 = is.imageZoomOut(image1, w, h);
      ImageIO.write(image2, "jpeg", response.getOutputStream());
    }
  }
}

在web.xml中增加相应的配置:
<servlet>
  <servlet-name>ImageServlet</servlet-name>
  <servlet-class>servlet.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>ImageServlet</servlet-name>
  <url-pattern>/imageServlet</url-pattern>
</servlet-mapping>

测试页面 http://www.feng123.com 下的:
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gbk" />
  </head>
  <body>
    图片缩放测试http://www.bt285.cn <br/>
    <img src="imageServlet" />
    <img src="imageServlet?x=0.9&y=0.9" />
    <img src="imageServlet?x=0.8&y=0.8" />
    <img src="imageServlet?x=0.7&y=0.7" />
    <img src="imageServlet?x=0.6&y=0.6" />
    <img src="imageServlet?x=0.5&y=0.5" />
    <img src="imageServlet?x=0.4&y=0.4" />
    <img src="imageServlet?x=0.3&y=0.3" />
    <img src="imageServlet?x=0.2&y=0.2" />
    <img src="imageServlet?x=0.1&y=0.1" />
    <img src="imageServlet?x=0.08" />
    <img src="imageServlet?x=0.5&y=0.7" />
  </body>
</html>

posted on 2009-05-22 22:12 江苏520 阅读(2408) 评论(0)  编辑  收藏