posts - 495,comments - 227,trackbacks - 0
          http://www.open-open.com/lib/view/open1394859355853.html

          package com.pinker.util;
          import java.awt.Color;
          import java.awt.Graphics;
          import java.awt.Image;
          import java.awt.image.BufferedImage;
          import java.io.File;
          import java.io.IOException;
          import java.util.Arrays;
          import java.util.Iterator;

          import javax.imageio.IIOImage;
          import javax.imageio.ImageIO;
          import javax.imageio.ImageReader;
          import javax.imageio.ImageWriter;
          import javax.imageio.stream.ImageInputStream;
          import javax.imageio.stream.ImageOutputStream;
           
          /**
           * 圖像裁剪以及壓縮處理工具類
           *
           * 主要針對動態的GIF格式圖片裁剪之后,只出現一幀動態效果的現象提供解決方案
           *
           * 提供依賴三方包解決方案(針對GIF格式數據特征一一解析,進行編碼解碼操作)
           * 提供基于JDK Image I/O 的解決方案(JDK探索失敗)
           */
          public class ImageUtil2 {
           
              public enum IMAGE_FORMAT{
                  BMP("bmp"),
                  JPG("jpg"),
                  WBMP("wbmp"),
                  JPEG("jpeg"),
                  PNG("png"),
                  GIF("gif");
                   
                  private String value;
                  IMAGE_FORMAT(String value){
                      this.value = value;
                  }
                  public String getValue() {
                      return value;
                  }
                  public void setValue(String value) {
                      this.value = value;
                  }
              }
               
               
              /**
               * 獲取圖片格式
               * @param file   圖片文件
               * @return    圖片格式
               */
              public static String getImageFormatName(File file)throws IOException{
                  String formatName = null;
                   
                  ImageInputStream iis = ImageIO.createImageInputStream(file);
                  Iterator<ImageReader> imageReader =  ImageIO.getImageReaders(iis);
                  if(imageReader.hasNext()){
                      ImageReader reader = imageReader.next();
                      formatName = reader.getFormatName();
                  }
           
                  return formatName;
              }
               
              /*************************  基于三方包解決方案    *****************************/
              /**
               * 剪切圖片
               *
               * @param source        待剪切圖片路徑
               * @param targetPath    裁剪后保存路徑(默認為源路徑)
               * @param x                起始橫坐標
               * @param y                起始縱坐標
               * @param width            剪切寬度
               * @param height        剪切高度         
               *
               * @returns            裁剪后保存路徑(圖片后綴根據圖片本身類型生成)    
               * @throws IOException
               */
              public static String cutImage(String sourcePath , String targetPath , int x , int y , int width , int height) throws IOException{
                  File file = new File(sourcePath);
                  if(!file.exists()) {
                      throw new IOException("not found the image:" + sourcePath);
                  }
                  if(null == targetPath || targetPath.isEmpty()) targetPath = sourcePath;
                   
                  String formatName = getImageFormatName(file);
                  if(null == formatName) return targetPath;
                  formatName = formatName.toLowerCase();
                   
                  // 防止圖片后綴與圖片本身類型不一致的情況
                  String pathPrefix = getPathWithoutSuffix(targetPath);
                  targetPath = pathPrefix + formatName;
                   
                  // GIF需要特殊處理
                  if(IMAGE_FORMAT.GIF.getValue() == formatName){
                      GifDecoder decoder = new GifDecoder();  
                      int status = decoder.read(sourcePath);  
                      if (status != GifDecoder.STATUS_OK) {  
                          throw new IOException("read image " + sourcePath + " error!");  
                      }
           
                      AnimatedGifEncoder encoder = new AnimatedGifEncoder();
                      encoder.start(targetPath);
                      encoder.setRepeat(decoder.getLoopCount());  
                      for (int i = 0; i < decoder.getFrameCount(); i ++) {  
                          encoder.setDelay(decoder.getDelay(i));  
                          BufferedImage childImage = decoder.getFrame(i);
                          BufferedImage image = childImage.getSubimage(x, y, width, height);
                          encoder.addFrame(image);  
                      }  
                      encoder.finish();
                  }else{
                      BufferedImage image = ImageIO.read(file);
                      image = image.getSubimage(x, y, width, height);
                      ImageIO.write(image, formatName, new File(targetPath));
                  }
                  //普通圖片
                  BufferedImage image = ImageIO.read(file);
                  image = image.getSubimage(x, y, width, height);
                  ImageIO.write(image, formatName, new File(targetPath));
                  
                  return targetPath;
              }
               
              /**
               * 壓縮圖片
               * @param sourcePath       待壓縮的圖片路徑
               * @param targetPath    壓縮后圖片路徑(默認為初始路徑)
               * @param width            壓縮寬度
               * @param height        壓縮高度
               *
               * @returns                   裁剪后保存路徑(圖片后綴根據圖片本身類型生成)    
               * @throws IOException
               */
              public static String zoom(String sourcePath , String targetPath, int width , int height) throws IOException{
                  File file = new File(sourcePath);
                  if(!file.exists()) {
                      throw new IOException("not found the image :" + sourcePath);
                  }
                  if(null == targetPath || targetPath.isEmpty()) targetPath = sourcePath;
                   
                  String formatName = getImageFormatName(file);
                  if(null == formatName) return targetPath;
                  formatName = formatName.toLowerCase();
                   
                  // 防止圖片后綴與圖片本身類型不一致的情況
                  String pathPrefix = getPathWithoutSuffix(targetPath);
                  targetPath = pathPrefix + formatName;
                   
                  // GIF需要特殊處理
                  if(IMAGE_FORMAT.GIF.getValue() == formatName){
                      GifDecoder decoder = new GifDecoder();  
                      int status = decoder.read(sourcePath);  
                      if (status != GifDecoder.STATUS_OK) {  
                          throw new IOException("read image " + sourcePath + " error!");  
                      }
           
                      AnimatedGifEncoder encoder = new AnimatedGifEncoder();
                      encoder.start(targetPath);
                      encoder.setRepeat(decoder.getLoopCount());  
                      for (int i = 0; i < decoder.getFrameCount(); i ++) {  
                          encoder.setDelay(decoder.getDelay(i));  
                          BufferedImage image = zoom(decoder.getFrame(i), width , height);
                          encoder.addFrame(image);  
                      }  
                      encoder.finish();
                  }else{
                      BufferedImage image = ImageIO.read(file);
                      BufferedImage zoomImage = zoom(image , width , height);
                      ImageIO.write(zoomImage, formatName, new File(targetPath));
                  }
                  BufferedImage image = ImageIO.read(file);
                  BufferedImage zoomImage = zoom(image , width , height);
                  ImageIO.write(zoomImage, formatName, new File(targetPath));
                   
                  return targetPath;
              }
               
              /*********************** 基于JDK 解決方案     ********************************/
               
              /**
               * 讀取圖片
               * @param file 圖片文件
               * @return     圖片數據
               * @throws IOException
               */
              public static BufferedImage[] readerImage(File file) throws IOException{
                  BufferedImage sourceImage = ImageIO.read(file);
                  BufferedImage[] images = null;
                  ImageInputStream iis = ImageIO.createImageInputStream(file);
                  Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(iis);
                  if(imageReaders.hasNext()){
                      ImageReader reader = imageReaders.next();
                      reader.setInput(iis);
                      int imageNumber = reader.getNumImages(true);
                      images = new BufferedImage[imageNumber];
                      for (int i = 0; i < imageNumber; i++) {
                          BufferedImage image = reader.read(i);
                          if(sourceImage.getWidth() > image.getWidth() || sourceImage.getHeight() > image.getHeight()){
                              image = zoom(image, sourceImage.getWidth(), sourceImage.getHeight());
                          }
                          images[i] = image;
                      }
                      reader.dispose();
                      iis.close();
                  }
                  return images;
              }
               
              /**
               * 根據要求處理圖片
               *
               * @param images    圖片數組
               * @param x            橫向起始位置
               * @param y         縱向起始位置
               * @param width      寬度    
               * @param height    寬度
               * @return            處理后的圖片數組
               * @throws Exception
               */
              public static BufferedImage[] processImage(BufferedImage[] images , int x , int y , int width , int height) throws Exception{
                  if(null == images){
                      return images;
                  }
                  BufferedImage[] oldImages = images;
                  images = new BufferedImage[images.length];
                  for (int i = 0; i < oldImages.length; i++) {
                      BufferedImage image = oldImages[i];
                      images[i] = image.getSubimage(x, y, width, height);
                  }
                  return images;
              }
               
              /**
               * 寫入處理后的圖片到file
               *
               * 圖片后綴根據圖片格式生成
               *
               * @param images        處理后的圖片數據
               * @param formatName     圖片格式
               * @param file            寫入文件對象
               * @throws Exception
               */
              public static void writerImage(BufferedImage[] images ,  String formatName , File file) throws Exception{
                  Iterator<ImageWriter> imageWriters = ImageIO.getImageWritersByFormatName(formatName);
                  if(imageWriters.hasNext()){
                      ImageWriter writer = imageWriters.next();
                      String fileName = file.getName();
                      int index = fileName.lastIndexOf(".");
                      if(index > 0){
                          fileName = fileName.substring(0, index + 1) + formatName;
                      }
                      String pathPrefix = getFilePrefixPath(file.getPath());
                      File outFile = new File(pathPrefix + fileName);
                      ImageOutputStream ios = ImageIO.createImageOutputStream(outFile);
                      writer.setOutput(ios);
                       
                      if(writer.canWriteSequence()){
                          writer.prepareWriteSequence(null);
                          for (int i = 0; i < images.length; i++) {
                              BufferedImage childImage = images[i];
                              IIOImage image = new IIOImage(childImage, null , null);
                              writer.writeToSequence(image, null);
                          }
                          writer.endWriteSequence();
                      }else{
                          for (int i = 0; i < images.length; i++) {
                              writer.write(images[i]);
                          }
                      }
                       
                      writer.dispose();
                      ios.close();
                  }
              }
               
              /**
               * 剪切格式圖片
               *
               * 基于JDK Image I/O解決方案
               *
               * @param sourceFile        待剪切圖片文件對象
               * @param destFile                  裁剪后保存文件對象
               * @param x                    剪切橫向起始位置
               * @param y                 剪切縱向起始位置
               * @param width              剪切寬度    
               * @param height            剪切寬度
               * @throws Exception
               */
              public static void cutImage(File sourceFile , File destFile, int x , int y , int width , int height) throws Exception{
                  // 讀取圖片信息
                  BufferedImage[] images = readerImage(sourceFile);
                  // 處理圖片
                  images = processImage(images, x, y, width, height);
                  // 獲取文件后綴
                  String formatName = getImageFormatName(sourceFile);
                  destFile = new File(getPathWithoutSuffix(destFile.getPath()) + formatName);
           
                  // 寫入處理后的圖片到文件
                  writerImage(images, formatName , destFile);
              }
               
               
               
              /**
               * 獲取系統支持的圖片格式
               */
              public static void getOSSupportsStandardImageFormat(){
                  String[] readerFormatName = ImageIO.getReaderFormatNames();
                  String[] readerSuffixName = ImageIO.getReaderFileSuffixes();
                  String[] readerMIMEType = ImageIO.getReaderMIMETypes();
                  System.out.println("========================= OS supports reader ========================");
                  System.out.println("OS supports reader format name :  " + Arrays.asList(readerFormatName));
                  System.out.println("OS supports reader suffix name :  " + Arrays.asList(readerSuffixName));
                  System.out.println("OS supports reader MIME type :  " + Arrays.asList(readerMIMEType));
                   
                  String[] writerFormatName = ImageIO.getWriterFormatNames();
                  String[] writerSuffixName = ImageIO.getWriterFileSuffixes();
                  String[] writerMIMEType = ImageIO.getWriterMIMETypes();
                   
                  System.out.println("========================= OS supports writer ========================");
                  System.out.println("OS supports writer format name :  " + Arrays.asList(writerFormatName));
                  System.out.println("OS supports writer suffix name :  " + Arrays.asList(writerSuffixName));
                  System.out.println("OS supports writer MIME type :  " + Arrays.asList(writerMIMEType));
              }
               
              /**
               * 壓縮圖片
               * @param sourceImage    待壓縮圖片
               * @param width          壓縮圖片高度
               * @param heigt          壓縮圖片寬度
               */
              private static BufferedImage zoom(BufferedImage sourceImage , int width , int height){
                  BufferedImage zoomImage = new BufferedImage(width, height, sourceImage.getType());
                  Image image = sourceImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
                  Graphics gc = zoomImage.getGraphics();
                  gc.setColor(Color.WHITE);
                  gc.drawImage( image , 0, 0, null);
                  return zoomImage;
              }
               
              /**
               * 獲取某個文件的前綴路徑
               *
               * 不包含文件名的路徑
               *
               * @param file   當前文件對象
               * @return
               * @throws IOException
               */
              public static String getFilePrefixPath(File file) throws IOException{
                  String path = null;
                  if(!file.exists()) {
                      throw new IOException("not found the file !" );
                  }
                  String fileName = file.getName();
                  path = file.getPath().replace(fileName, "");
                  return path;
              }
               
              /**
               * 獲取某個文件的前綴路徑
               *
               * 不包含文件名的路徑
               *
               * @param path   當前文件路徑
               * @return       不包含文件名的路徑
               * @throws Exception
               */
              public static String getFilePrefixPath(String path) throws Exception{
                  if(null == path || path.isEmpty()) throw new Exception("文件路徑為空!");
                  int index = path.lastIndexOf(File.separator);
                  if(index > 0){
                      path = path.substring(0, index + 1);
                  }
                  return path;
              }
               
              /**
               * 獲取不包含后綴的文件路徑
               *
               * @param src
               * @return
               */
              public static String getPathWithoutSuffix(String src){
                  String path = src;
                  int index = path.lastIndexOf(".");
                  if(index > 0){
                      path = path.substring(0, index + 1);
                  }
                  return path;
              }
               
              /**
               * 獲取文件名
               * @param filePath        文件路徑
               * @return                文件名
               * @throws IOException
               */
              public static String getFileName(String filePath) throws IOException{
                  File file = new File(filePath);
                  if(!file.exists()) {
                      throw new IOException("not found the file !" );
                  }
                  return file.getName();
              }
               
              /**
               * @param args
               * @throws Exception
               */
              public static void main(String[] args) throws Exception {
                  // 獲取系統支持的圖片格式
                  //ImageCutterUtil.getOSSupportsStandardImageFormat();
                   
                  try {
                      // 起始坐標,剪切大小
                      int x = 100;
                      int y = 75;
                      int width = 100;
                      int height = 100;
                      // 參考圖像大小
                      int clientWidth = 300;
                      int clientHeight = 250;
                       
                       
                      File file = new File("C:\\1.jpg");
                      BufferedImage image = ImageIO.read(file);
                      double destWidth = image.getWidth();
                      double destHeight = image.getHeight();
                       
                      if(destWidth < width || destHeight < height)
                          throw new Exception("源圖大小小于截取圖片大小!");
                       
                      double widthRatio = destWidth / clientWidth;
                      double heightRatio = destHeight / clientHeight;
                       
                      x = Double.valueOf(x * widthRatio).intValue();
                      y = Double.valueOf(y * heightRatio).intValue();
                      width = Double.valueOf(width * widthRatio).intValue();
                      height = Double.valueOf(height * heightRatio).intValue();
                       
                      System.out.println("裁剪大小  x:" + x + ",y:" + y + ",width:" + width + ",height:" + height);
           
                      /************************ 基于三方包解決方案 *************************/
                      String formatName = getImageFormatName(file);
                      String pathSuffix = "." + formatName;
                      String pathPrefix = getFilePrefixPath(file);
                      String targetPath = pathPrefix  + System.currentTimeMillis() + pathSuffix;
                      targetPath = ImageUtil2.cutImage(file.getPath(), targetPath, x , y , width, height);
                       
                      String bigTargetPath = pathPrefix  + System.currentTimeMillis() + pathSuffix;
                      ImageUtil2.zoom(targetPath, bigTargetPath, 100, 100);
                       
                      String smallTargetPath = pathPrefix  + System.currentTimeMillis() + pathSuffix;
                      ImageUtil2.zoom(targetPath, smallTargetPath, 50, 50);
                       
                      /************************ 基于JDK Image I/O 解決方案(JDK探索失敗) *************************/
          //                File destFile = new File(targetPath);
          //                ImageCutterUtil.cutImage(file, destFile, x, y, width, height);
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
          posted on 2016-05-23 14:40 SIMONE 閱讀(1667) 評論(0)  編輯  收藏 所屬分類: JAVA
          主站蜘蛛池模板: 碌曲县| 左云县| 辰溪县| 海安县| 兴化市| 任丘市| 柘城县| 双鸭山市| 托克托县| 射洪县| 澜沧| 柳州市| 佛学| 肇源县| 如东县| 罗山县| 镇安县| 囊谦县| 呼图壁县| 监利县| 青州市| 弋阳县| 济源市| 宁德市| 铁岭市| 凌海市| 塔河县| 岑巩县| 德庆县| 睢宁县| 望都县| 万源市| 利津县| 哈巴河县| 米林县| 盖州市| 平昌县| 饶阳县| 罗源县| 拜城县| 盱眙县|