1 24 package org.riotfamily.common.image; 25 26 import java.awt.Graphics2D ; 27 import java.awt.RenderingHints ; 28 import java.awt.image.BufferedImage ; 29 import java.awt.image.RenderedImage ; 30 import java.io.File ; 31 import java.io.FileInputStream ; 32 import java.io.IOException ; 33 import java.io.InputStream ; 34 import java.util.Iterator ; 35 import java.util.Locale ; 36 37 import javax.imageio.IIOImage ; 38 import javax.imageio.ImageIO ; 39 import javax.imageio.ImageWriteParam ; 40 import javax.imageio.ImageWriter ; 41 import javax.imageio.plugins.jpeg.JPEGImageWriteParam ; 42 import javax.imageio.stream.ImageOutputStream ; 43 44 import org.riotfamily.common.util.FormatUtils; 45 import org.springframework.util.Assert; 46 47 52 public class ImageIOThumbnailer implements Thumbnailer { 53 54 static { 55 System.setProperty("java.awt.headless", "true"); 56 } 57 58 private static final String FORMAT_JPG = "jpg"; 59 60 private static final String FORMAT_PNG = "png"; 61 62 private int maxCrop = 0; 63 64 public void setMaxCrop(int maxCrop) { 65 this.maxCrop = maxCrop; 66 } 67 68 public void renderThumbnail(File source, File dest, int width, int height) 69 throws IOException { 70 71 BufferedImage originalImage = readImage(new FileInputStream (source)); 72 boolean alpha = originalImage.getColorModel().hasAlpha(); 73 74 int imageWidth = originalImage.getWidth(null); 75 int imageHeight = originalImage.getHeight(null); 76 77 int thumbWidth; 78 int thumbHeight; 79 80 double scaleX = (double) width / (double) imageWidth; 81 double scaleY = (double) height / (double) imageHeight; 82 83 double scale = Math.min(Math.max(scaleX, scaleY), 1); 84 thumbWidth = (int) (imageWidth * scale); 85 thumbHeight = (int) (imageHeight * scale); 86 double cropFactor = (double) maxCrop / 100; 87 88 if ((thumbWidth - width > cropFactor * thumbWidth) 89 || (thumbHeight - height > cropFactor * thumbHeight)) { 90 91 scaleX = width / (imageWidth - cropFactor * imageWidth); 92 scaleY = height / (imageHeight - cropFactor * imageHeight); 93 scale = Math.min(Math.min(scaleX, scaleY), 1); 94 } 95 96 thumbWidth = (int) (imageWidth * scale); 97 thumbHeight = (int) (imageHeight * scale); 98 99 BufferedImage thumbImage = new BufferedImage (thumbWidth, 100 thumbHeight, alpha 101 ? BufferedImage.TYPE_INT_ARGB 102 : BufferedImage.TYPE_INT_RGB); 103 104 Graphics2D graphics2D = thumbImage.createGraphics(); 105 graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 106 RenderingHints.VALUE_INTERPOLATION_BICUBIC); 107 108 graphics2D.drawImage(originalImage, 0, 0, thumbWidth, thumbHeight, null); 109 110 int x = Math.max((thumbWidth - width) / 2, 0); 111 int y = Math.max((thumbHeight - height) / 2, 0); 112 if (x > 0 || y > 0) { 113 thumbWidth = Math.min(thumbWidth, width); 114 thumbHeight = Math.min(thumbHeight, height); 115 thumbImage = thumbImage.getSubimage(x, y, thumbWidth, thumbHeight); 116 } 117 118 writeImage(thumbImage, dest); 119 } 120 121 private BufferedImage readImage(InputStream in) throws IOException { 122 try { 123 return ImageIO.read(in); 124 } 125 finally { 126 try { 127 in.close(); 128 } 129 catch (Exception e) { 130 } 131 } 132 } 133 134 private void writeImage(RenderedImage im, File dest) throws IOException { 135 ImageWriter writer = null; 136 ImageOutputStream ios = null; 137 try { 138 String formatName = FormatUtils.getExtension(dest.getName()).toLowerCase(); 139 if (!formatName.equals(FORMAT_JPG) && !formatName.equals(FORMAT_PNG)) { 140 formatName = FORMAT_JPG; 141 } 142 Iterator it = ImageIO.getImageWritersByFormatName(formatName); 143 if (it.hasNext()) { 144 writer = (ImageWriter ) it.next(); 145 } 146 Assert.notNull(writer, "No ImageWriter available for format " 147 + formatName); 148 149 ios = ImageIO.createImageOutputStream(dest); 150 writer.setOutput(ios); 151 152 ImageWriteParam iwparam = null; 153 154 if (formatName.equals(FORMAT_JPG)) { 155 iwparam = new JPEGImageWriteParam (Locale.getDefault()); 156 iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 157 iwparam.setCompressionQuality(1); 158 } 159 160 writer.write(null, new IIOImage (im, null, null), iwparam); 161 ios.flush(); 162 } 163 finally { 164 if (writer != null) { 165 writer.dispose(); 166 } 167 if (ios != null) { 168 ios.close(); 169 } 170 } 171 } 172 173 } 174 | Popular Tags |