用JAVA处理图片文件

在图片上传时,要进行上传图片的处理,因此整理了一个图片工具类,完成图片的截取。

package image.util;

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.imageio.ImageIO;

/**
 * 图片工具类,完成图片的截取
 *
 * @author XXXX created at 2008-6-19
 * @since 1.0
 * @version
 */
public class ImageHelper {

 /**
  * 压缩Gif图片
  *
  * @param source
  *            源文件路径
  * @param dist
  *            目标文件路径
  * @param width
  *            期望宽度
  * @param height
  *            期望高度
  * @throws Exception
  *             异常
  */
 public static void resizeGIF(String source, String dist, int width,
   int height) throws Exception {

  //读入处理的图片
  File srcImg = new File(source);

  //将图片文件输入IO流
  InputStream is = new FileInputStream(srcImg);

   //生成一个GifDecoder 

  GifDecoder gifDecoder = new GifDecoder();
  if (GifDecoder.STATUS_FORMAT_ERROR == gifDecoder.read(is)) {//调用read方法读入文件流,出错时,抛出异常。
   throw new NotSupportImageFormatException(//自定义的一个异常类。
     "The file to be resized is not a valid gif file.");
  }

 

  File destImg = new File(dist);
  OutputStream os = new FileOutputStream(destImg);
  // 动态画面编码器
  AnimatedGifEncoder animatedGifEncoder = new AnimatedGifEncoder();
  animatedGifEncoder.start(os);
  // 设置循环显示的次数
  animatedGifEncoder.setRepeat(gifDecoder.getLoopCount());
  animatedGifEncoder.setQuality(19);

  // 循环得到每一帧
  int frameCount = gifDecoder.getFrameCount();
  for (int i = 0; i < frameCount; i++) {

   BufferedImage sourceFrame = gifDecoder.getFrame(i);
   // 缩放
   /*
    * BufferedImage targetFrame = zoom(sourceFrame, width, height,
    * maxWidthLimit, maxHeigthLimit);
    */
   BufferedImage targetFrame = resize(sourceFrame, width, height);
   // 设置每帧显示间隔时间
   animatedGifEncoder.setDelay(gifDecoder.getDelay(i));

   animatedGifEncoder.addFrame(targetFrame);

  }

  animatedGifEncoder.finish();
 }

 /**
  * 判断一个文件类型名称,是否为图片类型
  *
  * @param fileType
  *            文件类型名称
  * @return 是PNG, GIF, JPG图片类型为true否则为false
  */
 public static boolean isImage(String fileType) {
  if (isGif(fileType) || isJpg(fileType) || isPng(fileType))
   return true;
  else
   return false;
 }

 public static boolean isGif(String fileType) {
  if (fileType != null && fileType.trim().equalsIgnoreCase("GIF"))
   return true;
  else
   return false;
 }

 public static boolean isJpg(String fileType) {
  if (fileType != null && fileType.trim().equalsIgnoreCase("JPG"))
   return true;
  else
   return false;
 }

 public static boolean isPng(String fileType) {
  if (fileType != null && fileType.trim().equalsIgnoreCase("PNG"))
   return true;
  else
   return false;
 }

 /**
  * 获取图片文件的文件类型,JPG, PNG, GIF,如果非图片类型那么返回Undefined
  *
  * @param srcFileName
  *            图片全路明
  * @return 图片文件类型JPG, PNG, GIF 如果非图片则为Undefined
  */
 public static String getImageType(String srcFileName) {
  FileInputStream imgFile = null;
  byte[] b = new byte[10];
  int l = -1;
  try {
   imgFile = new FileInputStream(srcFileName);
   l = imgFile.read(b);
   imgFile.close();
  } catch (Exception e) {
   return "Undefined";
  }
  if (l == 10) {
   byte b0 = b[0];
   byte b1 = b[1];
   byte b2 = b[2];
   byte b3 = b[3];
   byte b6 = b[6];
   byte b7 = b[7];
   byte b8 = b[8];
   byte b9 = b[9];
   if (b0 == (byte) 'G' && b1 == (byte) 'I' && b2 == (byte) 'F') {
    return "GIF";
   } else if (b1 == (byte) 'P' && b2 == (byte) 'N' && b3 == (byte) 'G') {
    return "PNG";
   } else if (b6 == (byte) 'J' && b7 == (byte) 'F' && b8 == (byte) 'I'
     && b9 == (byte) 'F') {
    return "JPG";
   } else {
    return "Undefined";
   }
  } else {
   return "Undefined";
  }
 }

 /**
  * JPG文件Resize方法
  *
  * @param source
  *            源文件地址
  * @param dist
  *            目标文件地址
  * @param width
  *            目标宽度
  * @param height
  *            目标高度
  * @throws Exception
  *             异常信息
  */
 public static void resizeJPG(String source, String dist, int width,
   int height) throws Exception {
  if (!isJpg(getImageType(source)))
   throw new Exception(
     "The source file is not a jpeg file or not exist!");
  BufferedImage sourceImage = ImageIO.read(new File(source));
  BufferedImage targetImage = resize(sourceImage, width, height);
  ImageIO.write(targetImage, "jpg", new File(dist));
 }

 /**
  * 实现图像的等比缩放
  *
  * @param source
  * @param targetW
  * @param targetH
  * @return
  */
 private static BufferedImage resize(BufferedImage source, int targetW,
   int targetH) {
  // targetW,targetH分别表示目标长和宽
  int type = source.getType();
  BufferedImage target = null;
  double sx = (double) targetW / source.getWidth();
  double sy = (double) targetH / source.getHeight();
  // 这里想实现在targetW,targetH范围内实现等比缩放。如果不需要等比缩放
  // 则将下面的if else语句注释即可
  if (sx < sy) {
   // sx = sy;
   targetW = (int) (sx * source.getWidth());
  } else {
   // sy = sx;
   targetH = (int) (sy * source.getHeight());
  }

  if (type == BufferedImage.TYPE_CUSTOM) { // handmade
   ColorModel cm = source.getColorModel();
   WritableRaster raster = cm.createCompatibleWritableRaster(targetW,
     targetH);
   boolean alphaPremultiplied = cm.isAlphaPremultiplied();
   target = new BufferedImage(cm, raster, alphaPremultiplied, null);
  } else
   target = new BufferedImage(targetW, targetH, type);
  Graphics2D g = target.createGraphics();
  // smoother than exlax:
  g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
    RenderingHints.VALUE_INTERPOLATION_BICUBIC);
  g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));
  g.dispose();
  return target;
 }

 /**
  * 实现图像的等比缩放和缩放后的截取
  *
  * @param inFilePath
  *            要截取文件的路径
  * @param outFilePath
  *            截取后输出的路径
  * @param width
  *            要截取宽度
  * @param hight
  *            要截取的高度
  * @param proportion
  * @throws Exception
  */

 public static void saveImageAsJpg(String inFilePath, String outFilePath,
   int width, int hight, boolean proportion) throws Exception {
  File file = new File(inFilePath);
  InputStream in = new FileInputStream(file);
  File saveFile = new File(outFilePath);

  BufferedImage srcImage = ImageIO.read(in);
  if (width > 0 || hight > 0) {
   // 原图的大小
   int sw = srcImage.getWidth();
   int sh = srcImage.getHeight();
   // 如果原图像的大小小于要缩放的图像大小,直接将要缩放的图像复制过去
   if (sw > width && sh > hight) {
    srcImage = resize(srcImage, width, hight);
   } else {
    String fileName = saveFile.getName();
    String formatName = fileName.substring(fileName
      .lastIndexOf('.') + 1);
    ImageIO.write(srcImage, formatName, saveFile);
    return;
   }
  }
  // 缩放后的图像的宽和高
  int w = srcImage.getWidth();
  int h = srcImage.getHeight();
  // 如果缩放后的图像和要求的图像宽度一样,就对缩放的图像的高度进行截取
  if (w == width) {
   // 计算X轴坐标
   int x = 0;
   int y = h / 2 - hight / 2;
   saveSubImage(srcImage, new Rectangle(x, y, width, hight), saveFile);
  }
  // 否则如果是缩放后的图像的高度和要求的图像高度一样,就对缩放后的图像的宽度进行截取
  else if (h == hight) {
   // 计算X轴坐标
   int x = w / 2 - width / 2;
   int y = 0;
   saveSubImage(srcImage, new Rectangle(x, y, width, hight), saveFile);
  }
  in.close();
 }

 /**
  * 实现缩放后的截图
  *
  * @param image
  *            缩放后的图像
  * @param subImageBounds
  *            要截取的子图的范围
  * @param subImageFile
  *            要保存的文件
  * @throws IOException
  */
 private static void saveSubImage(BufferedImage image,
   Rectangle subImageBounds, File subImageFile) throws IOException {
  if (subImageBounds.x < 0 || subImageBounds.y < 0
    || subImageBounds.width - subImageBounds.x > image.getWidth()
    || subImageBounds.height - subImageBounds.y > image.getHeight()) {
   System.out.println("Bad   subimage   bounds");
   return;
  }
  BufferedImage subImage = image.getSubimage(subImageBounds.x,
    subImageBounds.y, subImageBounds.width, subImageBounds.height);
  String fileName = subImageFile.getName();
  String formatName = fileName.substring(fileName.lastIndexOf('.') + 1);
  ImageIO.write(subImage, formatName, subImageFile);
 }

}

 

这里用到了AnimatedGifEncoder、GifDecoder、LZWEncoder 、NeuQuant类可以从网络上下载,这些是不错的GIF解码和编码操作库。

posted @ 2008-10-17 15:01  zhanlh  阅读(2098)  评论(0编辑  收藏  举报