1 10 package org.mmbase.util.images; 11 12 import java.awt.image.renderable.ParameterBlock ; 13 import javax.media.jai.*; 14 import javax.media.jai.operator.*; 15 import java.awt.image.IndexColorModel ; 16 import java.awt.Transparency ; 17 import java.util.*; 18 import java.util.regex.*; 19 import java.io.*; 20 import com.sun.media.jai.codec.*; 21 22 import org.mmbase.util.logging.*; 23 24 31 public class JAIImageConverter implements ImageConverter { 32 33 private static final Logger log = Logging.getLoggerInstance(JAIImageConverter.class); 34 35 38 public void init(Map params) { 39 log.info("Starting JAI convertor"); 40 } 41 42 43 46 public byte[] convertImage(byte[] input, String sourceFormat, List commands) { 47 String format; 48 byte[] pict=null; 49 try { 50 ByteArraySeekableStream bin = new ByteArraySeekableStream(input); 51 PlanarImage img = JAI.create("stream", bin); 52 53 format = getConvertFormat(commands); 55 if (format.equals("asis")) format = sourceFormat; 56 57 if (! (format.equals("gif") || format.equals("png")) && 59 img.getColorModel()instanceof IndexColorModel ) { 60 IndexColorModel icm = (IndexColorModel ) img.getColorModel(); 61 if (icm.getTransparency() == Transparency.BITMASK) { 62 byte[][] data = new byte[3][icm.getMapSize()]; 63 icm.getReds(data[0]); 64 icm.getGreens(data[1]); 65 icm.getBlues(data[2]); 66 LookupTableJAI lut = new LookupTableJAI(data); 67 img = JAI.create("lookup", img, lut); 68 log.debug("palette-color image converted to RGB"); 69 } 70 } 71 72 img = doConvertCommands(img, commands); 73 74 ByteArrayOutputStream bout = new ByteArrayOutputStream(); 75 76 JAI.create("encode", img, bout, format, null); 77 pict = bout.toByteArray(); 78 } catch(Exception e) { 79 log.error(Logging.stackTrace(e)); 80 } 81 return pict; 82 } 83 84 91 private String getConvertFormat(List params) { 92 String format = null; 93 94 for (Iterator t = params.iterator(); t.hasNext();) { 95 String key=(String )t.next(); 96 int pos = key.indexOf('('); 97 int pos2 = key.lastIndexOf(')'); 98 if (pos!=-1 && pos2!=-1) { 99 String type = key.substring(0, pos); 100 String cmd = key.substring(pos + 1, pos2); 101 if (type.equals("f")) { 102 if (! (cmd.equals("asis") && format != null)) { 103 format = cmd.toLowerCase(); 104 } 105 break; 106 } 107 } 108 } 109 if (format == null) format = Factory.getDefaultImageFormat(); 110 if (format.equals("jpg")) format="jpeg"; 112 return format; 113 } 114 117 private PlanarImage doConvertCommands(PlanarImage img, List params) { 118 Iterator t = params.iterator(); 119 while (t.hasNext()) { 120 try { 121 String key=(String )t.next(); 122 int pos = key.indexOf('('); 123 int pos2 = key.lastIndexOf(')'); 124 if (pos!=-1 && pos2 != -1) { 125 String type = key.substring(0, pos); 126 String cmd = key.substring(pos + 1, pos2); 127 String [] tokens = cmd.split("[x,\\n\\r]"); 128 if (log.isDebugEnabled()) { 129 log.debug("getCommands(): type=" + type + " cmd=" + cmd); 130 log.debug("Image is now " + img.getWidth() + "x" + img.getHeight()); 131 log.debug(" or " + img.getMinX() + "-" + img.getMaxX() + ".." + img.getMinY() + "-" + img.getMaxY()); 132 } 133 type = Imaging.getAlias(type); 137 if (type.equals("geometry")) { 138 String xString = tokens.length > 0 ? tokens[0] : ""; 139 String yString = tokens.length > 1 ? tokens[1] : ""; 140 141 Matcher matchX = Imaging.GEOMETRY.matcher(xString); 142 xString = matchX.matches() ? matchX.group(1) : ""; 143 Matcher matchY = Imaging.GEOMETRY.matcher(yString); 144 yString = matchY.matches() ? matchY.group(1) : ""; 145 146 String options = (matchX.matches() ? matchX.group(2) : "") + (matchY.matches() ? matchY.group(2) : ""); 147 148 boolean aspectRatio = true; 149 boolean area = false; 150 boolean percentage = false; 151 152 for (int j = 0 ; j < options.length(); j++) { 153 char o = options.charAt(j); 154 if (o == '%') percentage = true; 155 if (o == '@') area = true; 156 if (o == '!') aspectRatio = false; 157 } 158 159 int x = "".equals(xString) ? 0 : Integer.parseInt(xString); 160 int y = "".equals(yString) ? 0 : Integer.parseInt(yString); 161 162 if (x == 0) { 163 x = Math.round((float) img.getWidth() * y / img.getHeight()); 164 } 165 if (area) { 166 float a = x; 167 if (img.getWidth() * img.getHeight() > a) { 168 float ratio = (float) img.getWidth() / img.getHeight();; 169 x = (int) Math.floor(Math.sqrt(a * ratio)); 170 y = (int) Math.floor(Math.sqrt(a / ratio)); 171 } else { 172 x = img.getWidth(); 173 y = img.getHeight(); 174 } 175 } 176 177 if (y == 0) { 178 y = Math.round((float) img.getHeight() * x / img.getWidth()); 179 } 180 181 if (percentage) { 182 x = img.getWidth() * x / 100; 183 y = img.getHeight() * y / 100; 184 aspectRatio = false; 185 } 186 img = size(img, x, y, aspectRatio); 187 } else if (type.equals("border")) { 188 int x = Integer.parseInt(tokens[0]); 189 int y = tokens.length > 1 ? Integer.parseInt(tokens[1]) : x; 190 img = border(img, x ,y); 191 } else if (type.equals("rotate")) { 192 int a = Integer.parseInt(tokens[0]); 193 img = rotate(img, 0, 0,a); 194 } else if (type.equals("part")) { 195 int x1 = Integer.parseInt(tokens[0]); 196 int y1 = Integer.parseInt(tokens[1]); 197 int x2 = Integer.parseInt(tokens[2]); 198 int y2 = Integer.parseInt(tokens[3]); 199 if (x2 > img.getWidth()) x2 = img.getWidth(); 200 if (y2 > img.getHeight()) y2 = img.getHeight(); 201 if (x1 > x2) x1 = x2 - 1; 202 if (y1 > y2) y1 = y2 - 1; 203 img = crop(img, x1, y1, x2, y2); 204 } 205 } else { 206 if (key.equals("negate")) { 207 img = negate(img); 208 } else if (key.equals("border")) { 209 img = border(img, 1, 1); 210 } else if (key.equals("flop")) { 211 img = flop(img); 212 } else if (key.equals("flip")) { 213 img = flip(img); 214 } 215 } 216 } catch(Exception e) { 217 log.error(e.getMessage(), e); 218 } 219 } 220 return img; 221 } 222 223 226 protected static PlanarImage crop(PlanarImage inImg,int x1,int y1, int x2,int y2) { 227 Interpolation interp = Interpolation.getInstance(Interpolation.INTERP_NEAREST); 228 ParameterBlock params = new ParameterBlock (); 229 params.addSource(inImg); 230 params.add((float)x1); params.add((float)y1); params.add((float)(x2 - x1)); params.add((float)(y2 - y1)); params.add(interp); PlanarImage outImg = JAI.create("crop", params); 236 return outImg; 237 } 238 239 248 protected static PlanarImage size(PlanarImage inImg,int width,int height, boolean maintainAspectRation) { 249 Interpolation interp = Interpolation.getInstance(Interpolation.INTERP_NEAREST); 250 int curwidth=inImg.getWidth(); 251 int curheight=inImg.getHeight(); 252 float sx=((float)width/curwidth); 253 float sy=((float)height/curheight); 254 if (maintainAspectRation) { 255 if (sy<sx) { 257 sx=sy; 258 } else { 259 sy=sx; 260 } 261 } 262 ParameterBlock params = new ParameterBlock (); 263 params.addSource(inImg); 264 params.add(sx); params.add(sy); params.add(0F); params.add(0F); params.add(interp); PlanarImage outImg = JAI.create("scale", params); 270 return outImg; 271 } 272 273 279 protected static PlanarImage negate(PlanarImage inImg) { 280 Interpolation interp = Interpolation.getInstance(Interpolation.INTERP_NEAREST); 281 ParameterBlock params = new ParameterBlock (); 282 params.addSource(inImg); 283 params.add(interp); PlanarImage outImg = JAI.create("invert", params); 285 return outImg; 286 } 287 288 296 protected static PlanarImage rotate(PlanarImage inImg,int x,int y,int a) { 297 Interpolation interp = Interpolation.getInstance(Interpolation.INTERP_NEAREST); 298 ParameterBlock params = new ParameterBlock (); 299 params.addSource(inImg); 300 params.add((float)x); params.add((float)y); params.add((float)Math.toRadians((double)(a))); params.add(interp); PlanarImage outImg = JAI.create("rotate", params); 305 return outImg; 306 } 307 308 316 protected static PlanarImage border(PlanarImage inImg, int xpadding,int ypadding) { 317 ParameterBlock params = new ParameterBlock (); 318 params.addSource(inImg); 319 params.add(xpadding); params.add(xpadding); params.add(ypadding); params.add(ypadding); params.add(BorderExtender.BORDER_ZERO); params.add(null); 326 PlanarImage outImg = JAI.create("border", params); 327 return outImg; 328 } 329 330 336 protected static PlanarImage flop(PlanarImage inImg) { 337 ParameterBlock params = new ParameterBlock (); 338 params.addSource(inImg); 339 params.add(TransposeDescriptor.FLIP_HORIZONTAL); PlanarImage outImg = JAI.create("transpose", params); 341 return outImg; 342 } 343 344 350 protected static PlanarImage flip(PlanarImage inImg) { 351 ParameterBlock params = new ParameterBlock (); 352 params.addSource(inImg); 353 params.add(TransposeDescriptor.FLIP_VERTICAL); PlanarImage outImg = JAI.create("transpose", params); 355 return outImg; 356 } 357 358 361 protected static PlanarImage loadImage(String filename) { 362 ParameterBlock pb = new ParameterBlock (); 363 pb.add(filename); 364 PlanarImage image = JAI.create("fileload",pb); 365 if (image==null) { 366 log.warn("Can't load image"); 367 } 368 return image; 369 } 370 371 372 } 373 | Popular Tags |