歡迎您光臨本站 註冊首頁

Java:圖片縮放演算法(down scaling)

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0

  1. Bilinear

  2. BiCubic

  3. Area_Average

  4. Progressive Bilinear

  當圖片縮小到原圖的一半以下時,bilinear的效果就不好了,再小下去,bicubic的也不夠好,最好的效果是area_average演算法,但是這個需要花太多的時間,可以使用改進過的bilinear演算法,效果跟area average差不多,速度在bilinear和bicubic之間,但是當圖片非常大,綻放到非常小時,花的時間比bicubic多得多,但是比area average少得多,效果與area average差不多,還是不錯的

  Progressive Bilinear Scaling

  We know that a significant problem with the quality of the bilinear approach occurs when the downscale is by more than 50 percent. So what if we compen- sated for that problem by scaling iteratively toward the final size, scaling down by exactly 50 percent each time until the final iteration, when we scale by 50 percent or less? Then we would account for all of the pixels along the way that should figure into the final image.

  // 縮小圖片,縮小時可以使用改進過的bilinear, bicubic插值演算法

  // 但是轉換透明圖片時如果使用單緩衝區會出問題,這時每次都要創建一個緩衝區才可以

  public static BufferedImage getFasterDownScaledInstance(BufferedImage img,

  int targetWidth,

  int targetHeight,

  Object hint,

  boolean progressive) {

  int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB

  : BufferedImage.TYPE_INT_ARGB;

  BufferedImage ret = (BufferedImage) img;

  BufferedImage scratchImage = null;

  Graphics2D g2d = null;

  int w = 0, h = 0;

  int prevW = ret.getWidth();

  int prevH = ret.getHeight();

  if (progressive) {

  // Use multistep technique: start with original size,

  // then scale down in multiple passes with drawImage()

  // until the target size is reached

  w = img.getWidth();

  h = img.getHeight();

  } else {

  // Use one-step technique: scale directly from original

  // size to target size with a single drawImage() call

  w = targetWidth;

  h = targetHeight;

  }

  do {

  if (targetWidth < img.getWidth() && progressive && w > targetWidth) {

  // 如果是縮小,寬縮小為原來的一半

  w >>>= 1;

  w = (w < targetWidth) ? targetWidth : w;

  } else {

  w = targetWidth;

  }

  if (targetHeight < img.getHeight() && progressive && h > targetHeight) {

  // 如果是縮小,高縮小為原來的一半

  h >>>= 1;

  h = (h < targetHeight) ? targetHeight : h;

  } else {

  h = targetHeight;

  }

  if (scratchImage == null) {

  // Use a single scratch buffer for all iterations

  // and then copy to the final, correctly sized image before

  // returning

  scratchImage = new BufferedImage(w, h, type);

  g2d = scratchImage.createGraphics();

  } else if (type == BufferedImage.TYPE_INT_ARGB && scratchImage != null && g2d != null) {

  // 透明圖片不能使用單緩存

  g2d.dispose();

  scratchImage = new BufferedImage(w, h, type);

  g2d = scratchImage.createGraphics();

  }

  g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);

  g2d.drawImage(ret, 0, 0, w, h, 0, 0, prevW, prevH, null);

  prevW = w;

  prevH = h;

  ret = scratchImage;

  } while (w != targetWidth || h != targetHeight);

  if (g2d != null) {

  g2d.dispose();

  }

  // If we used a target size, the results into it

  if (targetWidth != ret.getWidth() || targetHeight != ret.getHeight()) {

  scratchImage = new BufferedImage(targetWidth, targetHeight, type);

  g2d = scratchImage.createGraphics();

  g2d.drawImage(ret, 0, 0, null);

  g2d.dispose();

  ret = scratchImage;

  }

  return ret;

  }


[火星人 ] Java:圖片縮放演算法(down scaling)已經有1258次圍觀

http://coctec.com/docs/java/show-post-59812.html