1
22
23 package com.liferay.util;
24
25 import com.sun.imageio.plugins.gif.GIFImageReader;
26 import com.sun.imageio.plugins.jpeg.JPEGImageReader;
27 import com.sun.imageio.plugins.png.PNGImageReader;
28 import com.sun.media.jai.codec.ImageCodec;
29 import com.sun.media.jai.codec.ImageDecoder;
30
31 import java.awt.geom.AffineTransform;
32 import java.awt.image.AffineTransformOp;
33 import java.awt.image.BufferedImage;
34 import java.awt.image.DataBuffer;
35 import java.awt.image.RenderedImage;
36 import java.awt.image.SampleModel;
37
38 import java.io.ByteArrayInputStream;
39 import java.io.File;
40 import java.io.IOException;
41 import java.io.InputStream;
42 import java.io.OutputStream;
43
44 import java.util.Iterator;
45
46 import javax.imageio.ImageIO;
47 import javax.imageio.ImageReader;
48 import javax.imageio.stream.FileCacheImageInputStream;
49
50 import javax.media.jai.RenderedImageAdapter;
51
52 import net.jmge.gif.Gif89Encoder;
53
54 import org.apache.commons.logging.Log;
55 import org.apache.commons.logging.LogFactory;
56
57
63 public class ImageUtil {
64
65 public static final String TYPE_BMP = "bmp";
66
67 public static final String TYPE_GIF = "gif";
68
69 public static final String TYPE_JPEG = "jpeg";
70
71 public static final String TYPE_PNG = "png";
72
73 public static final String TYPE_TIFF = "tiff";
74
75 public static final String TYPE_NOT_AVAILABLE = "na";
76
77 public static void encodeGIF(RenderedImage renderedImage, OutputStream out)
78 throws IOException {
79
80 Gif89Encoder encoder = new Gif89Encoder(
81 getBufferedImage(renderedImage));
82
83 encoder.encode(out);
84 }
85
86 public static void encodeWBMP(RenderedImage renderedImage, OutputStream out)
87 throws InterruptedException, IOException {
88
89 BufferedImage bufferedImage = getBufferedImage(renderedImage);
90
91 SampleModel sampleModel = bufferedImage.getSampleModel();
92
93 int type = sampleModel.getDataType();
94
95 if ((bufferedImage.getType() != BufferedImage.TYPE_BYTE_BINARY) ||
96 (type < DataBuffer.TYPE_BYTE) || (type > DataBuffer.TYPE_INT) ||
97 (sampleModel.getNumBands() != 1) ||
98 (sampleModel.getSampleSize(0) != 1)) {
99
100 BufferedImage binaryImage = new BufferedImage(
101 bufferedImage.getWidth(), bufferedImage.getHeight(),
102 BufferedImage.TYPE_BYTE_BINARY);
103
104 binaryImage.getGraphics().drawImage(bufferedImage, 0, 0, null);
105
106 renderedImage = binaryImage;
107 }
108
109 if (!ImageIO.write(renderedImage, "wbmp", out)) {
110
111
113 out.write(0);
114 out.write(0);
115 out.write(_toMultiByte(bufferedImage.getWidth()));
116 out.write(_toMultiByte(bufferedImage.getHeight()));
117
118 DataBuffer dataBuffer = bufferedImage.getData().getDataBuffer();
119
120 int size = dataBuffer.getSize();
121
122 for (int i = 0; i < size; i++) {
123 out.write((byte)dataBuffer.getElem(i));
124 }
125 }
126 }
127
128 public static BufferedImage getBufferedImage(RenderedImage renderedImage) {
129 if (renderedImage instanceof BufferedImage) {
130 return (BufferedImage)renderedImage;
131 }
132 else {
133 RenderedImageAdapter adapter = new RenderedImageAdapter(
134 renderedImage);
135
136 return adapter.getAsBufferedImage();
137 }
138 }
139
140 public static ImageBag read(File file) throws IOException {
141 return read(FileUtil.getBytes(file));
142 }
143
144 public static ImageBag read(byte[] bytes) throws IOException {
145 RenderedImage renderedImage = null;
146 String type = TYPE_NOT_AVAILABLE;
147
148 InputStream is = null;
149 FileCacheImageInputStream fcis = null;
150
151 try {
152 is = new ByteArrayInputStream(bytes);
153 fcis = new FileCacheImageInputStream(is, null);
154
155 Iterator itr = ImageIO.getImageReaders(fcis);
156
157 while (itr.hasNext()) {
158 ImageReader reader = (ImageReader)itr.next();
159
160 if (reader instanceof GIFImageReader) {
161 type = TYPE_GIF;
162 }
163 else if (reader instanceof JPEGImageReader) {
164 type = TYPE_JPEG;
165 }
166 else if (reader instanceof PNGImageReader) {
167 type = TYPE_PNG;
168 }
169
170 reader.dispose();
171 }
172
173 if (!type.equals(TYPE_NOT_AVAILABLE)) {
174 renderedImage = ImageIO.read(fcis);
175 }
176
177 if (renderedImage == null) {
178 renderedImage = _getRenderedImage("BMP", bytes);
179
180 if (renderedImage != null) {
181 type = TYPE_BMP;
182 }
183 }
184
185 if (renderedImage == null) {
186 renderedImage = _getRenderedImage("TIFF", bytes);
187
188 if (renderedImage != null) {
189 type = TYPE_TIFF;
190 }
191 }
192
193 if (renderedImage == null) {
194 renderedImage = _getRenderedImage("GIF", bytes);
195
196 if (renderedImage != null) {
197 type = TYPE_GIF;
198 }
199 }
200
201 if (renderedImage == null) {
202 renderedImage = _getRenderedImage("JPEG", bytes);
203
204 if (renderedImage != null) {
205 type = TYPE_JPEG;
206 }
207 }
208
209 if (renderedImage == null) {
210 renderedImage = _getRenderedImage("PNG", bytes);
211
212 if (renderedImage != null) {
213 type = TYPE_PNG;
214 }
215 }
216 }
217 finally {
218 if (is != null) {
219 try {
220 is.close();
221 }
222 catch (IOException ioe) {
223 if (_log.isWarnEnabled()) {
224 _log.warn(ioe);
225 }
226 }
227 }
228
229 if (fcis != null) {
230 try {
231 fcis.close();
232 }
233 catch (IOException ioe) {
234 if (_log.isDebugEnabled()) {
235 _log.debug(ioe);
236 }
237 }
238 }
239 }
240
241 return new ImageBag(renderedImage, type);
242 }
243
244 public static RenderedImage scale(
245 RenderedImage renderedImage, double factor) {
246
247 AffineTransformOp op = new AffineTransformOp(
248 AffineTransform.getScaleInstance(factor, factor), null);
249
250 BufferedImage bufferedImage = getBufferedImage(renderedImage);
251
252 return op.filter(bufferedImage, null);
253 }
254
255 public static RenderedImage scale(
256 RenderedImage renderedImage, int maxHeight, int maxWidth) {
257
258 int imageHeight = renderedImage.getHeight();
259 int imageWidth = renderedImage.getWidth();
260
261 if (maxHeight == 0) {
262 maxHeight = imageHeight;
263 }
264
265 if (maxWidth == 0) {
266 maxWidth = imageWidth;
267 }
268
269 if ((imageHeight <= maxHeight) && (imageWidth <= maxWidth)) {
270 return renderedImage;
271 }
272
273 double factor = 0.1;
274
275 int heightDelta = imageHeight - maxHeight;
276 int widthDelta = imageWidth - maxWidth;
277
278 if (heightDelta > widthDelta) {
279 factor = (double)maxHeight / imageHeight;
280 }
281 else {
282 factor = (double)maxWidth / imageWidth;
283 }
284
285 return scale(renderedImage, factor);
286 }
287
288 private static RenderedImage _getRenderedImage(String name, byte[] bytes) {
289 RenderedImage renderedImage = null;
290
291 InputStream is = null;
292
293 try {
294 is = new ByteArrayInputStream(bytes);
295
296 ImageDecoder decoder = ImageCodec.createImageDecoder(
297 name, is, null);
298
299 renderedImage = decoder.decodeAsRenderedImage();
300 }
301 catch (Exception e) {
302 if (_log.isDebugEnabled()) {
303 _log.debug(name + ": " + e.getMessage());
304 }
305 }
306 finally {
307 if (is != null) {
308 try {
309 is.close();
310 }
311 catch (IOException ioe) {
312 if (_log.isWarnEnabled()) {
313 _log.warn(ioe);
314 }
315 }
316 }
317 }
318
319 return renderedImage;
320 }
321
322 private static byte[] _toMultiByte(int intValue) {
323 int numBits = 32;
324 int mask = 0x80000000;
325
326 while (mask != 0 && (intValue & mask) == 0) {
327 numBits--;
328 mask >>>= 1;
329 }
330
331 int numBitsLeft = numBits;
332 byte[] multiBytes = new byte[(numBitsLeft + 6) / 7];
333
334 int maxIndex = multiBytes.length - 1;
335
336 for (int b = 0; b <= maxIndex; b++) {
337 multiBytes[b] = (byte)((intValue >>> ((maxIndex - b) * 7)) & 0x7f);
338
339 if (b != maxIndex) {
340 multiBytes[b] |= (byte)0x80;
341 }
342 }
343
344 return multiBytes;
345 }
346
347 private static Log _log = LogFactory.getLog(ImageUtil.class);
348
349 }