001: /**
002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
003: *
004: * Permission is hereby granted, free of charge, to any person obtaining a copy
005: * of this software and associated documentation files (the "Software"), to deal
006: * in the Software without restriction, including without limitation the rights
007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008: * copies of the Software, and to permit persons to whom the Software is
009: * furnished to do so, subject to the following conditions:
010: *
011: * The above copyright notice and this permission notice shall be included in
012: * all copies or substantial portions of the Software.
013: *
014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
020: * SOFTWARE.
021: */package com.liferay.util;
022:
023: import com.sun.imageio.plugins.gif.GIFImageReader;
024: import com.sun.imageio.plugins.jpeg.JPEGImageReader;
025: import com.sun.imageio.plugins.png.PNGImageReader;
026: import com.sun.media.jai.codec.ImageCodec;
027: import com.sun.media.jai.codec.ImageDecoder;
028:
029: import java.awt.geom.AffineTransform;
030: import java.awt.image.AffineTransformOp;
031: import java.awt.image.BufferedImage;
032: import java.awt.image.DataBuffer;
033: import java.awt.image.RenderedImage;
034: import java.awt.image.SampleModel;
035:
036: import java.io.ByteArrayInputStream;
037: import java.io.File;
038: import java.io.IOException;
039: import java.io.InputStream;
040: import java.io.OutputStream;
041:
042: import java.util.Iterator;
043:
044: import javax.imageio.ImageIO;
045: import javax.imageio.ImageReader;
046: import javax.imageio.stream.FileCacheImageInputStream;
047:
048: import javax.media.jai.RenderedImageAdapter;
049:
050: import net.jmge.gif.Gif89Encoder;
051:
052: import org.apache.commons.logging.Log;
053: import org.apache.commons.logging.LogFactory;
054:
055: /**
056: * <a href="ImageUtil.java.html"><b><i>View Source</i></b></a>
057: *
058: * @author Brian Wing Shun Chan
059: *
060: */
061: public class ImageUtil {
062:
063: public static final String TYPE_BMP = "bmp";
064:
065: public static final String TYPE_GIF = "gif";
066:
067: public static final String TYPE_JPEG = "jpeg";
068:
069: public static final String TYPE_PNG = "png";
070:
071: public static final String TYPE_TIFF = "tiff";
072:
073: public static final String TYPE_NOT_AVAILABLE = "na";
074:
075: public static void encodeGIF(RenderedImage renderedImage,
076: OutputStream out) throws IOException {
077:
078: Gif89Encoder encoder = new Gif89Encoder(
079: getBufferedImage(renderedImage));
080:
081: encoder.encode(out);
082: }
083:
084: public static void encodeWBMP(RenderedImage renderedImage,
085: OutputStream out) throws InterruptedException, IOException {
086:
087: BufferedImage bufferedImage = getBufferedImage(renderedImage);
088:
089: SampleModel sampleModel = bufferedImage.getSampleModel();
090:
091: int type = sampleModel.getDataType();
092:
093: if ((bufferedImage.getType() != BufferedImage.TYPE_BYTE_BINARY)
094: || (type < DataBuffer.TYPE_BYTE)
095: || (type > DataBuffer.TYPE_INT)
096: || (sampleModel.getNumBands() != 1)
097: || (sampleModel.getSampleSize(0) != 1)) {
098:
099: BufferedImage binaryImage = new BufferedImage(bufferedImage
100: .getWidth(), bufferedImage.getHeight(),
101: BufferedImage.TYPE_BYTE_BINARY);
102:
103: binaryImage.getGraphics().drawImage(bufferedImage, 0, 0,
104: null);
105:
106: renderedImage = binaryImage;
107: }
108:
109: if (!ImageIO.write(renderedImage, "wbmp", out)) {
110:
111: // See http://www.jguru.com/faq/view.jsp?EID=127723
112:
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()
119: .getDataBuffer();
120:
121: int size = dataBuffer.getSize();
122:
123: for (int i = 0; i < size; i++) {
124: out.write((byte) dataBuffer.getElem(i));
125: }
126: }
127: }
128:
129: public static BufferedImage getBufferedImage(
130: RenderedImage renderedImage) {
131: if (renderedImage instanceof BufferedImage) {
132: return (BufferedImage) renderedImage;
133: } else {
134: RenderedImageAdapter adapter = new RenderedImageAdapter(
135: renderedImage);
136:
137: return adapter.getAsBufferedImage();
138: }
139: }
140:
141: public static ImageBag read(File file) throws IOException {
142: return read(FileUtil.getBytes(file));
143: }
144:
145: public static ImageBag read(byte[] bytes) throws IOException {
146: RenderedImage renderedImage = null;
147: String type = TYPE_NOT_AVAILABLE;
148:
149: InputStream is = null;
150: FileCacheImageInputStream fcis = null;
151:
152: try {
153: is = new ByteArrayInputStream(bytes);
154: fcis = new FileCacheImageInputStream(is, null);
155:
156: Iterator itr = ImageIO.getImageReaders(fcis);
157:
158: while (itr.hasNext()) {
159: ImageReader reader = (ImageReader) itr.next();
160:
161: if (reader instanceof GIFImageReader) {
162: type = TYPE_GIF;
163: } else if (reader instanceof JPEGImageReader) {
164: type = TYPE_JPEG;
165: } else if (reader instanceof PNGImageReader) {
166: type = TYPE_PNG;
167: }
168:
169: reader.dispose();
170: }
171:
172: if (!type.equals(TYPE_NOT_AVAILABLE)) {
173: renderedImage = ImageIO.read(fcis);
174: }
175:
176: if (renderedImage == null) {
177: renderedImage = _getRenderedImage("BMP", bytes);
178:
179: if (renderedImage != null) {
180: type = TYPE_BMP;
181: }
182: }
183:
184: if (renderedImage == null) {
185: renderedImage = _getRenderedImage("TIFF", bytes);
186:
187: if (renderedImage != null) {
188: type = TYPE_TIFF;
189: }
190: }
191:
192: if (renderedImage == null) {
193: renderedImage = _getRenderedImage("GIF", bytes);
194:
195: if (renderedImage != null) {
196: type = TYPE_GIF;
197: }
198: }
199:
200: if (renderedImage == null) {
201: renderedImage = _getRenderedImage("JPEG", bytes);
202:
203: if (renderedImage != null) {
204: type = TYPE_JPEG;
205: }
206: }
207:
208: if (renderedImage == null) {
209: renderedImage = _getRenderedImage("PNG", bytes);
210:
211: if (renderedImage != null) {
212: type = TYPE_PNG;
213: }
214: }
215: } finally {
216: if (is != null) {
217: try {
218: is.close();
219: } catch (IOException ioe) {
220: if (_log.isWarnEnabled()) {
221: _log.warn(ioe);
222: }
223: }
224: }
225:
226: if (fcis != null) {
227: try {
228: fcis.close();
229: } catch (IOException ioe) {
230: if (_log.isDebugEnabled()) {
231: _log.debug(ioe);
232: }
233: }
234: }
235: }
236:
237: return new ImageBag(renderedImage, type);
238: }
239:
240: public static RenderedImage scale(RenderedImage renderedImage,
241: double factor) {
242:
243: AffineTransformOp op = new AffineTransformOp(AffineTransform
244: .getScaleInstance(factor, factor), null);
245:
246: BufferedImage bufferedImage = getBufferedImage(renderedImage);
247:
248: return op.filter(bufferedImage, null);
249: }
250:
251: public static RenderedImage scale(RenderedImage renderedImage,
252: int maxHeight, int maxWidth) {
253:
254: int imageHeight = renderedImage.getHeight();
255: int imageWidth = renderedImage.getWidth();
256:
257: if (maxHeight == 0) {
258: maxHeight = imageHeight;
259: }
260:
261: if (maxWidth == 0) {
262: maxWidth = imageWidth;
263: }
264:
265: if ((imageHeight <= maxHeight) && (imageWidth <= maxWidth)) {
266: return renderedImage;
267: }
268:
269: double factor = 0.1;
270:
271: int heightDelta = imageHeight - maxHeight;
272: int widthDelta = imageWidth - maxWidth;
273:
274: if (heightDelta > widthDelta) {
275: factor = (double) maxHeight / imageHeight;
276: } else {
277: factor = (double) maxWidth / imageWidth;
278: }
279:
280: return scale(renderedImage, factor);
281: }
282:
283: private static RenderedImage _getRenderedImage(String name,
284: byte[] bytes) {
285: RenderedImage renderedImage = null;
286:
287: InputStream is = null;
288:
289: try {
290: is = new ByteArrayInputStream(bytes);
291:
292: ImageDecoder decoder = ImageCodec.createImageDecoder(name,
293: is, null);
294:
295: renderedImage = decoder.decodeAsRenderedImage();
296: } catch (Exception e) {
297: if (_log.isDebugEnabled()) {
298: _log.debug(name + ": " + e.getMessage());
299: }
300: } finally {
301: if (is != null) {
302: try {
303: is.close();
304: } catch (IOException ioe) {
305: if (_log.isWarnEnabled()) {
306: _log.warn(ioe);
307: }
308: }
309: }
310: }
311:
312: return renderedImage;
313: }
314:
315: private static byte[] _toMultiByte(int intValue) {
316: int numBits = 32;
317: int mask = 0x80000000;
318:
319: while (mask != 0 && (intValue & mask) == 0) {
320: numBits--;
321: mask >>>= 1;
322: }
323:
324: int numBitsLeft = numBits;
325: byte[] multiBytes = new byte[(numBitsLeft + 6) / 7];
326:
327: int maxIndex = multiBytes.length - 1;
328:
329: for (int b = 0; b <= maxIndex; b++) {
330: multiBytes[b] = (byte) ((intValue >>> ((maxIndex - b) * 7)) & 0x7f);
331:
332: if (b != maxIndex) {
333: multiBytes[b] |= (byte) 0x80;
334: }
335: }
336:
337: return multiBytes;
338: }
339:
340: private static Log _log = LogFactory.getLog(ImageUtil.class);
341:
342: }
|