2017-03-08 3 views
0

Java Spring MVC Web Application에는 모든 크기의 이미지를 업로드 할 수있는 옵션이 있습니다. 현재 지정된 너비보다 큰 업로드 된 이미지의 크기를 줄이는 API가 있습니다. 나는 그것을 위해 다음 코드를 사용자바 업로드 중에 이미지 압축

import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.image.BufferedImage; 
import java.awt.image.renderable.ParameterBlock; 
import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.util.Properties; 
import javax.imageio.ImageIO; 
import javax.media.jai.JAI; 
import javax.media.jai.PlanarImage; 
import javax.media.jai.RenderedOp; 

public class ImageRescale 
{ 
    private static RenderingHints hints; 

    static 
    { 
     hints = new RenderingHints(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); 
     hints.put(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_COLOR_RENDER_QUALITY); 
     hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 

     /* 
     * this block is to silence the warning that we're not using JAI 
     * native acceleration but are using the pure java implementation. 
     */ 
     Properties p = new Properties(System.getProperties()); 
     p.put("com.sun.media.jai.disableMediaLib", "true"); 
     System.setProperties(p); 
    } 


    public static byte[] getScaledInstance(byte[] image, int maxWidth) 
    { 
     InputStream in = new ByteArrayInputStream(image); 
     BufferedImage img = null; 
     try 
     { 
      img = ImageIO.read(in); 

     double scale = (double) maxWidth/img.getWidth(); 
     if (scale > 1.0d) 
     { 
      return image; 
     } 
     else if (scale > 0.5d && scale < 1.0d) 
     { 
      return getByteArray(getScaledDownByGraphics(img, scale)); 
     } 
     else if (scale <= 0.5d) 
     { 
      return getByteArray(getScaledDownByJAI(img, scale)); 
     } 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
     return image; 
    } 

    public static byte[] getByteArray(BufferedImage img) 
    { 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     byte[] imageInByte = null; 
     try 
     { 
      ImageIO.write(img, "jpg", baos); 
      baos.flush(); 
      imageInByte = baos.toByteArray(); 
      baos.close(); 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
     return imageInByte; 
    } 

    /** 
    * See http://www.digitalsanctuary.com/tech-blog/java/how-to-resize-uploaded-images-using-java-better-way.html 
    * This instance seems to produce quality images ONLY when you are 
    * scaling down to something less than 50% of the original size. 
    * @param img 
    * @param scale 
    * @return the scaled image 
    */ 
    private static BufferedImage getScaledDownByJAI(BufferedImage img, double scale) 
    { 
     if(scale > 1.0d) 
     { 
      throw new RuntimeException("Can't scale according to " + scale + " : This method only scales down."); 
     } 
     PlanarImage originalImage = PlanarImage.wrapRenderedImage(img); 
     // now resize the image 
     ParameterBlock paramBlock = new ParameterBlock(); 
     paramBlock.addSource(originalImage); // The source image 
     paramBlock.add(scale); // The xScale 
     paramBlock.add(scale); // The yScale 
     paramBlock.add(0.0); // The x translation 
     paramBlock.add(0.0); // The y translation 
     RenderedOp resizedImage = JAI.create("SubsampleAverage", paramBlock, hints); 
     return resizedImage.getAsBufferedImage();  
    } 

    /** 
    * This method produces high quality images when target scale is greater 
    * than 50% of the original. 
    * @param img 
    * @param scale 
    * @return the scaled image 
    */ 
    private static BufferedImage getScaledDownByGraphics(BufferedImage img, double scale) 
    { 
     final float scaleFactor = 0.8f; 

       BufferedImage ret = (BufferedImage)img; 
       int w = img.getWidth(); 
       int h = img.getHeight(); 

       int targetWidth = (int)(img.getWidth() * scale); 
       int targetHeight = (int)(img.getHeight() * scale); 

       int loopCount = 0; 
       int maxLoopCount = 20; 
       BufferedImage tmp; 
       do { 
         if (w > targetWidth) { 
           w *= scaleFactor; 
           if (w < targetWidth) { 
             w = targetWidth; 
           } 
         } 
         if (h > targetHeight) { 
           h *= scaleFactor; 
           if (h < targetHeight) { 
             h = targetHeight; 
           } 
         } 
         tmp = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
         Graphics2D g2 = tmp.createGraphics(); 

         g2.addRenderingHints(hints); 
         g2.drawImage(ret, 0, 0, w, h, null); 
         g2.dispose(); 

         ret = tmp; 
         if(++loopCount > maxLoopCount) { 
           throw new RuntimeException("Hit maximum loop count " + maxLoopCount); 
         } 
       } while (w != targetWidth || h != targetHeight); 
       return ret;  
    } 
} 

는하지만 내가 지금 원하는 것은 모든 업로드 된 이미지를 압축하고 나는 이미지에 대한 웹 표준이라고 생각 주위 72 dpi에 자사의 해상도를 가지고하는 API입니다. 내가 이것을 성취 할 수있는 방법이 있나.

+1

"압축"이라고 쓰면 "크기를 조정 하시겠습니까?"라는 뜻입니까? 이미지의 크기가 mm 또는 인치로 측정되어야하는지 또는 이미지의 dpi를 알고 있는지를 알면이를 수행 할 수 있습니다. 이 정보는 이미지 파일의 메타 데이터에 포함되거나 별도로 전달되어야합니다. – Henry

+0

모든 이미지의 해상도가 약 72dpi가되도록하십시오. 너비와 높이를 줄이지 않고. –

답변

0

도움이 될지 확인해주세요.

/** 
* 
* @param bi image 
* @param mimeType type 
* @param quality quality 
* @return compressed image 
* @throws IOException on error 
*/ 
private static BufferedImage compressImage(BufferedImage bi, String mimeType 
     , float quality) throws IOException { 
    // converting buffered image to byte array 

    // do not compress GIFs 
    if (mimeType.equalsIgnoreCase("image/gif")) { 
     return bi; 
    } 

    ImageWriter writer = ImageIO.getImageWritersByMIMEType(mimeType).next(); 
    ImageWriteParam iwp = writer.getDefaultWriteParam(); 

    if (!mimeType.equalsIgnoreCase("image/png") && !mimeType.equalsIgnoreCase("image/bmp")) { 
     iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 
     iwp.setCompressionQuality(quality); 
    } 

    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    BufferedOutputStream bos = new java.io.BufferedOutputStream(baos); 
    ImageOutputStream ios = ImageIO.createImageOutputStream(bos); 
    writer.setOutput(ios); 

    IIOImage optimizedImage = new IIOImage(bi, null, null); 
    writer.write(null, optimizedImage, iwp); 
    writer.dispose(); 
    baos.flush(); 

    ByteArrayInputStream in = new ByteArrayInputStream(baos.toByteArray()); 
    return ImageIO.read(in); 
} 
관련 문제