001: package com.sun.portal.wireless.transcode;
002:
003: import java.net.URL;
004: import java.util.HashMap;
005: import java.util.Set;
006: import java.util.ArrayList;
007: import javax.imageio.ImageIO;
008: import java.awt.image.BufferedImage;
009: import java.awt.geom.AffineTransform;
010: import java.awt.image.AffineTransformOp;
011: import java.awt.Graphics2D;
012:
013: import java.io.IOException;
014: import java.io.OutputStream;
015: import java.io.InputStream;
016: import java.io.ByteArrayInputStream;
017: import java.io.ByteArrayOutputStream;
018: import java.util.Iterator;
019:
020: public class Transcoder {
021:
022: private static HashMap types;
023: private static ArrayList writerTypes;
024:
025: static {
026: types = new HashMap();
027: types.put("jpeg", "image/jpeg");
028: types.put("gif", "image/gif");
029: types.put("bmp", "image/bmp");
030: types.put("wbmp", "image/vnd.wap.wbmp");
031: types.put("jpg", "image/jpeg");
032: types.put("png", "image/png");
033:
034: writerTypes = new ArrayList();
035: String[] t = ImageIO.getWriterMIMETypes();
036: for (int i = 0; i < t.length; i++) {
037: writerTypes.add(t[i]);
038: }
039: System.setProperty("java.awt.headless", "true");
040:
041: }
042:
043: public Transcoder() {
044: }
045:
046: private URL imgurl;
047: private String targetType;
048: private int x, y;
049: private String srcFormat;
050: private InputStream inputStream;
051:
052: public void setImage(InputStream is, String format) {
053: inputStream = is;
054: srcFormat = format;
055: }
056:
057: // Saves the image URL to be transcoded
058: // returns the format of the image, null if it cant be determined.
059:
060: public String setImage(URL url) {
061:
062: imgurl = url;
063: String file = imgurl.getFile();
064: String ext = file.substring(file.lastIndexOf('.') + 1);
065: srcFormat = (String) types.get(ext);
066: return srcFormat;
067: }
068:
069: // Takes a preferred image type, and a set of acceptable image types.
070: // returns a format using the following algorithm:
071: // 1. return the preferred image type, if it is found in the acceptable list, and there is a writer available
072: // 2. return the first type from the acceptable set that has a writer available
073: // 3. return the type of the image set in imgurl (ie, no format changes will be done)
074:
075: public String setTargetType(String prefType, Set accept) {
076:
077: if (srcFormat == null) {
078: // cant proceed without knowing src image type
079: return null;
080: }
081: if (prefType == null)
082: prefType = srcFormat;
083: if (writerTypes.contains(prefType)
084: && (accept.contains(prefType)
085: || accept.contains("image/*") || accept
086: .contains("*/*"))) {
087: targetType = prefType;
088: } else if (accept != null) {
089: for (Iterator i = accept.iterator(); i.hasNext();) {
090: String type = (String) i.next();
091: if (writerTypes.contains(type)) {
092: targetType = type;
093: break;
094: }
095: }
096: if (targetType == null) {
097: if (accept.contains("image/*")
098: || accept.contains("*/*")
099: || accept.contains(srcFormat)) {
100: targetType = srcFormat;
101: }
102: }
103: }
104:
105: return targetType;
106: }
107:
108: // Sets the preferred width of the image
109: public void setX(int x) {
110: this .x = x;
111: }
112:
113: // Sets the preferred height of the image
114: public void setY(int y) {
115: this .y = y;
116:
117: }
118:
119: // Transcodes image to the given output stream
120:
121: public String transcode(OutputStream os) throws IOException {
122:
123: ByteArrayInputStream imgStream;
124: if (inputStream == null) {
125: inputStream = imgurl.openStream();
126: }
127: ByteArrayOutputStream tmpstream = new ByteArrayOutputStream();
128: byte[] arr = new byte[1024];
129: int cnt;
130: while ((cnt = inputStream.read(arr, 0, 1024)) > 0) {
131: tmpstream.write(arr, 0, cnt);
132: }
133: inputStream.close();
134: imgStream = new ByteArrayInputStream(tmpstream.toByteArray());
135: if (targetType == null || srcFormat == null) {
136: dump(imgStream, os);
137: return srcFormat;
138: }
139: if (targetType.equals(srcFormat) && (x == 0 || y == 0)) {
140: dump(imgStream, os);
141: return srcFormat;
142: }
143:
144: BufferedImage bi = ImageIO.read(imgStream);
145: if (x > 0 && y > 0) {
146: double h, w;
147: h = bi.getHeight();
148: w = bi.getWidth();
149: double targetx = x / w;
150: double targety = y / h;
151: AffineTransform transform = new AffineTransform();
152: transform.scale(targetx, targety);
153: AffineTransformOp op = new AffineTransformOp(transform,
154: AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
155: BufferedImage tmp = op.filter(bi, null);
156: bi = tmp;
157: }
158: Iterator readers = ImageIO.getImageReadersByMIMEType(srcFormat);
159: Iterator it = ImageIO.getImageWritersByMIMEType(targetType);
160: if (it.hasNext() && readers.hasNext()) {
161: String fmt = targetType.substring(6);
162: if (fmt.endsWith("wbmp")) {
163: fmt = "wbmp";
164: BufferedImage tmp = new BufferedImage(bi.getWidth(), bi
165: .getHeight(), BufferedImage.TYPE_BYTE_BINARY);
166: Graphics2D g = tmp.createGraphics();
167: g.drawImage(bi, null, 0, 0);
168: bi = tmp;
169:
170: }
171: if (ImageIO.write(bi, fmt, os) == false) {
172: imgStream.reset();
173: dump(imgStream, os);
174: return srcFormat;
175: }
176:
177: }
178:
179: else {
180: /* if(! it.hasNext()){
181: System.out.println("No writers");
182: }
183: if( ! readers.hasNext()){
184: System.out.println("No readers");
185: }
186: */
187: imgStream.reset();
188: dump(imgStream, os);
189: return srcFormat;
190: }
191: return targetType;
192:
193: }
194:
195: private void dump(InputStream is, OutputStream os)
196: throws IOException {
197: while (is.available() > 0)
198: os.write(is.read());
199: }
200:
201: }
|