链接地址:http://blog.sina.com.cn/s/blog_407a68fc0100nrba.html

package util;

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

import javax.imageio.ImageIO;

public class ImgThumb {
 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;

// update by libra
  double wt = w > width ? width : w;
  double ht = h > height ? height : h;

scaleH = (double) wt / (double) width;
  scaleV = (double) ht / (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 boolean scale(String source, String target, int width, int height) {
  File f = new File(source);
  try {
   BufferedImage bi = ImageIO.read(f);
   BufferedImage out = null;
   ImgThumb scal = new ImgThumb();
   int _width = bi.getWidth();// 宽
   int _height = bi.getHeight();// 高
   int[] _arr = getImageWidthAndHeight(_width, _height, width, height);
   out = scal.imageZoomOut(bi, _arr[0], _arr[1]);
   File t = new File(target);
   ImageIO.write(out, "jpg", t);
   return true;
  } catch (IOException e) {
   e.printStackTrace();
   return false;
  }
 }

public int[] picscale(String source, String target, int w, int h) {
  File f = new File(source);
  int[] arr = { 0, 0 };
  try {
   BufferedImage bi = ImageIO.read(f);
   BufferedImage out = null;
   ImgThumb scal = new ImgThumb();
   arr = getImageWidthAndHeight(bi.getWidth(), bi.getHeight(), w, h);
   out = scal.imageZoomOut(bi, arr[0], arr[1]);
   File t = new File(target);
   ImageIO.write(out, "jpg", t);
  } catch (IOException e) {
   e.printStackTrace();
  }
  return arr;
 }

private static int[] getImageWidthAndHeight(int orgW, int orgH, int avW,
   int avH) {
  int width = 0;
  int height = 0;

if (orgW > 0 && orgH > 0) {
   if (orgW / orgH >= avW / avH) {
    if (orgW > avW) {
     width = avW;
     height = (orgH * avW) / orgW;
    } else {
     width = orgW;
     height = orgH;
    }
    System.out.println("++Widht::::" + width + " Height::::"
      + height);
   } else {
    if (orgH > avH) {
     height = avH;
     width = (orgW * avH) / orgH;
    } else {
     width = orgW;
     height = orgH;
    }
    System.out.println("++Widht::::" + width + " Height::::"
      + height);
   }
  }
  int[] arr = new int[2];
  arr[0] = width;
  arr[1] = height;

// long start = System.currentTimeMillis();
  // int width = 0;
  // int height = 0;
  // if ((W / tarW) >= (H / tarH)) {// 宽的缩小比例大于高的
  // width = tarW;
  // height = H * tarW / W;
  // System.out.println(width + "  " + height);
  // } else {
  // height = tarH;
  // width = W * tarH / H;
  // System.out.println(width + "  " + height);
  // }
  // int[] arr = new int[2];
  // arr[0] = width;
  // arr[1] = height;
  // long end = System.currentTimeMillis();
  // System.out.println("宽高处理:" + (end - start));
  return arr;
 }

public static void main(String[] args) {
  ImgThumb is = new ImgThumb();
  long start = System.currentTimeMillis();
  is.scale("D:/1.gif", "D:/2.gif", 227, 400);
  long end = System.currentTimeMillis();
  System.out.println("时间:" + (end - start));
 }
}

最新文章

  1. js模拟抛出球运动
  2. ABP理论学习之开篇介绍
  3. Mvc模板页
  4. C#: 数据绑定
  5. python的行与缩进
  6. KMP算法---字符串匹配
  7. POJ 3685 二分套二分
  8. 关于在git添加远程地址的过程中遇到的问题
  9. 需求分析&amp;原型改进
  10. Node.js建立服务、路径处理与响应
  11. BSGS与exBSGS学习笔记
  12. C#基础知识回顾-- 属性与字段
  13. 《算法》第四章部分程序 part 13
  14. T-SQL编程中的异常处理-异常捕获(try catch)与抛出异常(throw)
  15. 导入(移动)数据到hive1.1.0表的方法
  16. bzoj 1132 几何
  17. php5.4以上 mysqli 实例操作mysql 增,删,改,查
  18. JZOJ.5280【NOIP2017模拟8.15】膜法师
  19. JAVA通过网站域名URL获取该网站的源码(2018
  20. 谈谈 epmd

热门文章

  1. (Problem 72)Counting fractions
  2. (iOS)推送常见问题
  3. 使用HISTCONTROL强制history忽略某条特定命令
  4. zookeeper leader作用
  5. POCO C++ lib开发环境构建
  6. BZOJ 1023
  7. hdoj 2544 最短路(最短路+Dijkstrea算法)
  8. Break the Chocolate(规律)
  9. asp导航条子菜单横向
  10. MessageDigest简单介绍