KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > knowgate > hipergate > Image


1 /*
2   Copyright (C) 2003 Know Gate S.L. All rights reserved.
3                       C/Oņa, 107 1š2 28050 Madrid (Spain)
4
5   Redistribution and use in source and binary forms, with or without
6   modification, are permitted provided that the following conditions
7   are met:
8
9   1. Redistributions of source code must retain the above copyright
10      notice, this list of conditions and the following disclaimer.
11
12   2. The end-user documentation included with the redistribution,
13      if any, must include the following acknowledgment:
14      "This product includes software parts from hipergate
15      (http://www.hipergate.org/)."
16      Alternately, this acknowledgment may appear in the software itself,
17      if and wherever such third-party acknowledgments normally appear.
18
19   3. The name hipergate must not be used to endorse or promote products
20      derived from this software without prior written permission.
21      Products derived from this software may not be called hipergate,
22      nor may hipergate appear in their name, without prior written
23      permission.
24
25   This library is distributed in the hope that it will be useful,
26   but WITHOUT ANY WARRANTY; without even the implied warranty of
27   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
28
29   You should have received a copy of hipergate License with this code;
30   if not, visit http://www.hipergate.org or mail to info@hipergate.org
31 */

32
33 package com.knowgate.hipergate;
34
35 import java.io.File JavaDoc;
36 import java.io.IOException JavaDoc;
37 import java.io.FileNotFoundException JavaDoc;
38 import java.io.FileInputStream JavaDoc;
39 import java.io.FileOutputStream JavaDoc;
40 import java.io.InputStream JavaDoc;
41 import java.io.OutputStream JavaDoc;
42 import java.io.ByteArrayOutputStream JavaDoc;
43
44 import java.sql.SQLException JavaDoc;
45 import java.sql.Connection JavaDoc;
46 import java.sql.Statement JavaDoc;
47 import java.sql.PreparedStatement JavaDoc;
48 import java.sql.ResultSet JavaDoc;
49
50 import java.net.URL JavaDoc;
51
52 import java.awt.MediaTracker JavaDoc;
53 import java.awt.RenderingHints JavaDoc;
54 import java.awt.Toolkit JavaDoc;
55 import java.awt.Frame JavaDoc;
56 import java.awt.Graphics2D JavaDoc;
57 import java.awt.image.BufferedImage JavaDoc;
58 import java.awt.image.RenderedImage JavaDoc;
59 import java.awt.image.ColorModel JavaDoc;
60 import java.awt.image.ComponentColorModel JavaDoc;
61 import java.awt.image.DataBuffer JavaDoc;
62 import java.awt.image.renderable.ParameterBlock JavaDoc;
63 import java.awt.color.ColorSpace JavaDoc;
64 import java.awt.Transparency JavaDoc;
65
66 import com.knowgate.debug.*;
67 import com.knowgate.jdc.JDCConnection;
68 import com.knowgate.misc.Base64Decoder;
69 import com.knowgate.misc.Gadgets;
70 import com.knowgate.dataobjs.DB;
71 import com.knowgate.dataobjs.DBBind;
72 import com.knowgate.dataobjs.DBPersist;
73
74 /**
75  * <p>Simple imaging transformations</p>
76  * @author Sergio Montoro Ten
77  * @version 2.1
78  * @see com.knowgate.dataxslt.Image
79  */

80
81 public class Image extends DBPersist {
82
83   private int iImagingLibrary;
84
85   private int iDimX;
86   private int iDimY;
87
88   private MediaTracker JavaDoc mediaTracker;
89
90   private java.awt.Image JavaDoc oImg;
91
92   /**
93    * Create empty image, use AWT imaging routines.
94    */

95   public Image() {
96     super(DB.k_images, "Image");
97     iImagingLibrary = USE_AWT;
98     mediaTracker = null;
99   }
100
101   /**
102    * Create empty image.
103    * @param iLibraryCode Imaging library to use. Either USE_AWT or USE_JAI.
104    * @throws IllegalArgumentException
105    */

106   public Image(int iLibraryCode) throws IllegalArgumentException JavaDoc {
107     super(DB.k_images, "Image");
108     setImagingLibrary(iLibraryCode);
109     mediaTracker = null;
110   }
111
112   /**
113    * Load image properties from database.
114    * @param oConn Database Connection.
115    * @param sImageId Image GUID at k_images table.
116    * @throws SQLException
117    */

118   public Image(JDCConnection oConn, String JavaDoc sImageId) throws SQLException JavaDoc {
119     super(DB.k_images, "Image");
120
121     iImagingLibrary = USE_AWT;
122     mediaTracker = null;
123
124     load(oConn, new Object JavaDoc[]{sImageId});
125   }
126
127   /**
128    * Load Image directly from a Java AWT abstract Image
129    * @param oAWTImage java.awt.Image object
130    * @param sImagePath Optional. Path to image file name.
131    * @param iLibraryCode Imaging library to use. Either USE_AWT or USE_JAI.
132    */

133   public Image(java.awt.Image JavaDoc oAWTImage, String JavaDoc sImagePath, int iLibrary) {
134     super(DB.k_images, "Image");
135
136     iImagingLibrary = iLibrary;
137     mediaTracker = null;
138
139     oImg = oAWTImage;
140
141     if (null!=sImagePath)
142       put(DB.path_image, sImagePath);
143   }
144
145   /**
146    * <p>Load Image properties from database using file path as key.</p>
147    * This method searched a file path into field path_image from k_images table.<br>
148    * @param oConn Database Connection
149    * @param oFile Image File Object
150    * @param sFilePath Full path to Image File (as stored at k_images.path_image)
151    * @throws SQLException
152    */

153   public Image(JDCConnection oConn, File JavaDoc oFile, String JavaDoc sFilePath) throws SQLException JavaDoc {
154     super(DB.k_images, "Image");
155
156     String JavaDoc sImageId;
157     PreparedStatement JavaDoc oStmt;
158     ResultSet JavaDoc oRSet;
159
160     iImagingLibrary = USE_AWT;
161     mediaTracker = null;
162
163     if (DebugFile.trace) DebugFile.writeln("new Image([Conenction]," + oFile.getAbsolutePath() + "," + sFilePath);
164
165     if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement(SELECT " + DB.gu_image + " FROM " + DB.k_images + " WHERE " + DB.path_image + "='" + sFilePath + "'");
166
167     oStmt = oConn.prepareStatement("SELECT " + DB.gu_image + " FROM " + DB.k_images + " WHERE " + DB.path_image + "=?", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
168     oStmt.setString(1, sFilePath);
169     oRSet = oStmt.executeQuery();
170     if (oRSet.next())
171       sImageId = oRSet.getString(1);
172     else
173       sImageId = null;
174     oRSet.close();
175     oStmt.close();
176
177     if (null==sImageId) {
178       put(DB.gu_image, Gadgets.generateUUID());
179     }
180     else {
181       put(DB.gu_image, sImageId);
182     }
183
184     put(DB.path_image, sFilePath);
185     put(DB.len_file, new Long JavaDoc(oFile.length()).intValue());
186   }
187
188   //----------------------------------------------------------------------------
189

190   /**
191    * <p>Set imaging library to use.</p>
192    * On many systems it is neccesary to have X-Windows started for being able to
193    * use AWT imaging routines.<br>
194    * @param iLibraryCode USE_AWT or USE_JAI
195    * @see http://java.sun.com/products/java-media/jai/
196    * @see http://java.sun.com/j2se/1.4.2/docs/api/
197    */

198   public void setImagingLibrary (int iLibraryCode) {
199
200     if (DebugFile.trace) {
201       switch (iLibraryCode) {
202         case USE_AWT:
203           DebugFile.writeln("Image.setImagingLibrary(USE_AWT)");
204           break;
205         case USE_JAI:
206           DebugFile.writeln("Image.setImagingLibrary(USE_JAI)");
207           break;
208         default:
209           DebugFile.writeln("Image.setImagingLibrary(" + String.valueOf(iLibraryCode) + ")");
210       }
211     }
212
213     if (iLibraryCode!=USE_AWT && iLibraryCode!=USE_JAI)
214       throw new IllegalArgumentException JavaDoc("Imaging library code must be Image.USE_AWT or Image.USE_JAI");
215
216     iImagingLibrary = iLibraryCode;
217   } // setImagingLibrary
218

219   //----------------------------------------------------------------------------
220

221   /**
222    * <p>Get active imaging library.</p>
223    * @return USE_AWT or USE_JAI
224    */

225   public int getImagingLibrary() {
226     return iImagingLibrary;
227   } // getImagingLibrary
228

229   //----------------------------------------------------------------------------
230

231   /**
232    * <p>Store image properties at database.</p>
233    * The image itself is kept as a disk file pointe by path_file field.<br>
234    * On saving the Image a GUID is automatically assigned if one is not provided.<br>
235    * Image file length, width and height are saved to len_file, dm_width and dm_height fields.<br>
236    * Only GIF 89a and JPG/JPEG images are recognized for automatic dimensions computation.<br>
237    * @param oConn Database Connection
238    * @throws SQLException
239    * @throws NoClassDefFoundError
240    * @throws UnsatisfiedLinkError hen JAI native libraries (*_jai.so) are not
241    * installed Sun JAI tries to use AWT which is slower but more compatible.
242    * Some libraries of AWT are requiered. Particularly from Fedora Core 2:<br>
243    * xorg-x11-devel (contains libXp.so, requiered by libawt.so),
244    * fontconfig, fontconfig-devel, xorg-x11-libs, xorg-x11-libs-data, xorg-x11-Mesa-libGL
245    */

246   public boolean store(JDCConnection oConn)
247     throws SQLException JavaDoc, UnsatisfiedLinkError JavaDoc, NoClassDefFoundError JavaDoc {
248     File JavaDoc oFile;
249     java.sql.Timestamp JavaDoc dtNow;
250
251     if (DebugFile.trace) {
252       DebugFile.writeln("Begin Image.store([Connection])");
253       DebugFile.incIdent();
254     }
255
256     dtNow = new java.sql.Timestamp JavaDoc(DBBind.getTime());
257
258     if (!AllVals.containsKey(DB.gu_image))
259       put(DB.gu_image, Gadgets.generateUUID());
260     else
261       replace(DB.dt_modified, dtNow);
262
263     if (!AllVals.containsKey(DB.id_img_type))
264       put(DB.id_img_type, getImageType());
265
266     try {
267
268       if (!AllVals.containsKey(DB.len_file)) {
269         oFile = new File JavaDoc(getString(DB.path_image));
270         put(DB.len_file, new Long JavaDoc(oFile.length()).intValue());
271       } // fi (len_file)
272

273       if (!AllVals.containsKey(DB.dm_width) && ! AllVals.containsKey(DB.dm_height)) {
274         try {
275           if (dimensions()) {
276             put(DB.dm_width, iDimX);
277             put(DB.dm_height, iDimY);
278           } // fi (dimensions())
279
}
280         catch (NullPointerException JavaDoc e) {
281           if (DebugFile.trace) DebugFile.writeln("Image.dimensions() - NullPointerException ");
282           new ErrorHandler(e);
283         }
284       } // fi (dm_width && dm_height)
285

286     }
287     catch (FileNotFoundException JavaDoc fnf) {
288       if (DebugFile.trace) DebugFile.writeln("FileNotFoundException:" + fnf.getMessage());
289     }
290     catch(IOException JavaDoc ioe) {
291         if (DebugFile.trace) DebugFile.writeln("IOException:" + ioe.getMessage());
292     }
293
294     boolean bRetVal = super.store(oConn);
295
296     if (DebugFile.trace) {
297       DebugFile.decIdent();
298       DebugFile.writeln("End Image.store([Connection]) : " + String.valueOf(bRetVal));
299     }
300
301     return bRetVal;
302   } // store
303

304   //----------------------------------------------------------------------------
305

306   /**
307    * Delete Image from database and from disk.
308    * @param oConn Database Connection
309    * @throws SQLException
310    */

311   public boolean delete(JDCConnection oConn) throws SQLException JavaDoc {
312     boolean bRetVal;
313     String JavaDoc sPath;
314     File JavaDoc oFile;
315     Statement JavaDoc oDlte;
316     PreparedStatement JavaDoc oStmt;
317     ResultSet JavaDoc oRSet;
318     int iCount;
319
320     if (DebugFile.trace) {
321       DebugFile.writeln("Begin Image.delete([Connection])");
322       DebugFile.incIdent();
323       if (DebugFile.trace) DebugFile.writeln("Connection.executeUpdate(DELETE FROM " + DB.k_x_cat_objs + " WHERE " + DB.gu_object + "='" + getStringNull(DB.gu_image, "null") + "' AND " + DB.id_class + "=" + String.valueOf(Image.ClassId) + ")");
324     }
325
326     oDlte = oConn.createStatement();
327     oDlte.executeUpdate("DELETE FROM " + DB.k_x_cat_objs + " WHERE " + DB.gu_object + "='" + getString(DB.gu_image) + "' AND " + DB.id_class + "=" + String.valueOf(Image.ClassId));
328     oDlte.close();
329
330     sPath = getString(DB.path_image);
331     if (sPath.startsWith("file://")) sPath = sPath.substring(7);
332
333     oFile = new File JavaDoc(sPath);
334
335     if (oFile.exists() && oFile.isFile()) {
336       oStmt = oConn.prepareStatement("SELECT COUNT(" + DB.gu_image + ") FROM " + DB.k_images + " WHERE " + DB.path_image + "=?", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
337       oStmt.setString(1, getString(DB.path_image));
338       oRSet = oStmt.executeQuery();
339       oRSet.next();
340       iCount = oRSet.getInt(1);
341       oRSet.close();
342       oStmt.close();
343
344       if (1==iCount)
345         bRetVal = oFile.delete();
346       else
347         bRetVal = true;
348     }
349     else
350       bRetVal = true;
351
352     if (bRetVal)
353       bRetVal = super.delete(oConn);
354
355     if (DebugFile.trace) {
356       DebugFile.decIdent();
357       DebugFile.writeln("End Image.delete([Connection]) : " + String.valueOf(bRetVal));
358     }
359
360     return bRetVal;
361   } // delete
362

363
364   //----------------------------------------------------------------------------
365
/**
366    * <p>Get image file extension in lowercase.</p>
367    */

368   public String JavaDoc getImageType() {
369     String JavaDoc sFilePath;;
370     String JavaDoc sRetVal;
371
372     if (DebugFile.trace) {
373       DebugFile.writeln("Begin Image.getImageType()");
374       DebugFile.incIdent();
375     }
376
377     sFilePath = getStringNull(DB.path_image,null);
378
379     if (sFilePath==null) return null;
380
381     int iDot = sFilePath.lastIndexOf(".");
382     if (iDot>0)
383       sRetVal = sFilePath.substring(++iDot).toLowerCase();
384     else
385       sRetVal = null;
386
387     if (DebugFile.trace) {
388       DebugFile.decIdent();
389       DebugFile.writeln("End Image.getImageType([Connection]) : " + (sRetVal!=null ? sRetVal : "null"));
390     }
391     return sRetVal;
392   } // getImageType
393

394   //----------------------------------------------------------------------------
395

396   public String JavaDoc getImageCodec() {
397     String JavaDoc sCodec;
398     String JavaDoc sType = getImageType();
399
400     if (sType.equalsIgnoreCase("jpg"))
401       sCodec = "jpeg";
402     else if (sType.equalsIgnoreCase("tif"))
403       sCodec = "tiff";
404     else
405       sCodec = sType;
406
407     return sCodec;
408   }
409
410   //----------------------------------------------------------------------------
411

412   private int unsigned (byte by) {
413     final byte MinusOne = -1;
414
415     return (by<0) ? ((int) (by*MinusOne))+128 : (int) by;
416   }
417
418   // ----------------------------------------------------------
419

420   private boolean dimensionsJAI()
421     throws IOException JavaDoc, FileNotFoundException JavaDoc, NullPointerException JavaDoc {
422
423     boolean bRetVal = false;
424
425     if (DebugFile.trace) {
426       DebugFile.writeln("Begin Image.dimensionsJAI()");
427       DebugFile.incIdent();
428     }
429
430     RenderedImage JavaDoc oImg;
431     com.sun.media.jai.codec.ImageDecoder oDecoder;
432
433     if (DebugFile.trace) DebugFile.writeln("new FileInputStream(" + getStringNull(DB.path_image,"null") + ")");
434
435     FileInputStream JavaDoc oInputStream = new FileInputStream JavaDoc(getString(DB.path_image));
436
437     oDecoder = com.sun.media.jai.codec.ImageCodec.createImageDecoder(getImageCodec(), oInputStream, null);
438
439     oImg = oDecoder.decodeAsRenderedImage();
440
441     iDimX = oImg.getWidth();
442     iDimY = oImg.getHeight();
443
444     oInputStream.close();
445
446     bRetVal = true;
447
448     if (DebugFile.trace) {
449       DebugFile.decIdent();
450       DebugFile.writeln("End Image.dimensionsJAI() : " + String.valueOf(bRetVal));
451     }
452
453     return bRetVal;
454   } // dimensionsJAI
455

456   // ----------------------------------------------------------
457

458   /**
459    * <p>Get image dimensions.</p>
460    * Dimensions are stored at dm_width and dm_height properties.<br>
461    * Only GIF 89a and JPG/JPEG images are supported
462    * @return <b>true</b> if dimensions where successfully computed,
463    * <b>false</b> if routine was unable to recognize file format.
464    * @throws IOException
465    * @throws FileNotFoundException
466    * @throws ArrayIndexOutOfBoundsException
467    * @throws NullPointerException
468    * @throws UnsatisfiedLinkError When JAI native libraries (*_jai.so) are not
469    * installed Sun JAI tries to use AWT which is slower but more compatible.
470    * Some libraries of AWT are requiered. Particularly from Fedora Core 2:<br>
471    * xorg-x11-devel (contains libXp.so, requiered by libawt.so),
472    * fontconfig, fontconfig-devel, xorg-x11-libs, xorg-x11-libs-data, xorg-x11-Mesa-libGL
473    */

474   public boolean dimensions()
475     throws IOException JavaDoc, FileNotFoundException JavaDoc, ArrayIndexOutOfBoundsException JavaDoc,
476            UnsatisfiedLinkError JavaDoc, NullPointerException JavaDoc {
477
478     boolean bRetVal;
479     File JavaDoc oFile;
480     FileInputStream JavaDoc oFileRead;
481     String JavaDoc sType;
482     int iFound;
483     int iFileLen;
484     byte byFile[];
485     byte by;
486
487     if (DebugFile.trace) {
488       DebugFile.writeln("Begin Image.dimensions()");
489       DebugFile.incIdent();
490     }
491
492     sType = getImageType();
493
494     if (sType!=null) {
495
496       if (USE_JAI==iImagingLibrary) {
497         try {
498           bRetVal = dimensionsJAI();
499         }
500           catch (IOException JavaDoc ioe) { if (DebugFile.trace) DebugFile.decIdent(); bRetVal = false; }
501       }
502       else
503         bRetVal = false;
504
505       if (!bRetVal) {
506         sType = sType.toUpperCase();
507
508         if (sType.equals("GIF")) {
509           byFile = new byte[16];
510
511           if (DebugFile.trace) DebugFile.writeln("new FileInputStream(" + getStringNull(DB.path_image,"null") + ")");
512
513           oFileRead = new FileInputStream JavaDoc(getString(DB.path_image));
514           oFileRead.read(byFile,0,16);
515           oFileRead.close();
516
517           iDimX = (unsigned(byFile[7]))*256 + (unsigned(byFile[6]));
518           iDimY = (unsigned(byFile[9]))*256 + (unsigned(byFile[8]));
519
520           if (DebugFile.trace) DebugFile.writeln("[width=" + String.valueOf(iDimX) + ",height=" + String.valueOf(iDimY) + "]");
521
522           bRetVal = true;
523         } // fi (sType==GIF)
524

525         else if (sType.equals("JPG") || sType.equals("JPEG")) {
526
527           if (DebugFile.trace) DebugFile.writeln("new File(" + getStringNull(DB.path_image,"null") + ")");
528
529           oFile = new File JavaDoc(getString(DB.path_image));
530
531           if (DebugFile.trace) DebugFile.writeln("filelen = " + String.valueOf(oFile.length()));
532
533           iFileLen = new Long JavaDoc(oFile.length()).intValue();
534
535           byFile = new byte[iFileLen];
536
537           oFileRead = new FileInputStream JavaDoc(oFile);
538           oFileRead.read(byFile, 0, iFileLen);
539           oFileRead.close();
540
541           iFound = 0;
542
543           for (int iPos=21;
544                iPos<iFileLen-10;
545                iPos = (2 + iPos + (unsigned(byFile[iPos + 1]) * 256 + unsigned(byFile[iPos+2]))) ) {
546
547             by = byFile[iPos];
548             if ((by>=0xC0 && by<=0xC3) || (by>=0xC5 && by<=0xC7) || (by>=0xC9 && by<=0xCB) || (by>=0xCD && by<=0xCF)) {
549               iFound = iPos;
550               break;
551             }
552           } // next (iPos)
553

554           if (0!=iFound) {
555             iDimY = (unsigned(byFile[iFound + 4]) * 256 + unsigned(byFile[iFound + 5]));
556             iDimX = (unsigned(byFile[iFound + 6]) * 256 + unsigned(byFile[iFound + 7]));
557
558             if (DebugFile.trace) DebugFile.writeln("[width=" + String.valueOf(iDimX) + ",height=" + String.valueOf(iDimY) + "]");
559
560             bRetVal = true;
561           }
562           else {
563             if (DebugFile.trace) DebugFile.writeln("JPEG dimensions bytecodes not found");
564             bRetVal = false;
565           }
566         }
567         else
568           bRetVal = false;
569         }
570       } // fi (sType)
571
else
572         bRetVal = false;
573
574     if (DebugFile.trace) {
575       DebugFile.decIdent();
576       DebugFile.writeln("End Image.dimensions() : " + String.valueOf(bRetVal));
577     }
578
579     return bRetVal;
580   } // dimensions
581

582   // ----------------------------------------------------------
583

584   private void drawAWTImage(OutputStream JavaDoc outStr, int iThumbWidth, int iThumbHeight, float fQuality) throws IOException JavaDoc, InstantiationException JavaDoc, InterruptedException JavaDoc {
585
586     String JavaDoc sInputURI;
587     Frame JavaDoc awtFrame;
588     com.sun.image.codec.jpeg.JPEGImageEncoder encoder;
589     com.sun.image.codec.jpeg.JPEGEncodeParam param;
590     BufferedImage JavaDoc thumbImage;
591     Graphics2D JavaDoc graphics2D;
592     URL JavaDoc oURI;
593
594     if (DebugFile.trace) {
595       DebugFile.writeln("Begin Image.drawAWTImage([OutputStream], " + String.valueOf(iThumbWidth) + "," + String.valueOf(iThumbHeight) + "," + String.valueOf(fQuality));
596       DebugFile.incIdent();
597     }
598
599     sInputURI = getString(DB.path_image);
600
601     if (sInputURI.startsWith("http://") || sInputURI.startsWith("https://")) {
602       oURI = new URL JavaDoc(sInputURI);
603
604       if (DebugFile.trace) DebugFile.writeln("java.awt.Toolkit.getDefaultToolkit().getImage([java.net.URL])");
605
606       oImg = Toolkit.getDefaultToolkit().getImage(oURI);
607     }
608     else {
609       if (DebugFile.trace) DebugFile.writeln("java.awt.Toolkit.getDefaultToolkit().getImage(sInputURI)");
610
611       oImg = Toolkit.getDefaultToolkit().getImage(sInputURI);
612     }
613
614     int iImageWidth = oImg.getWidth(null);
615     int iImageHeight = oImg.getHeight(null);
616
617     double thumbRatio = ((double) iThumbWidth) / ((double) iThumbHeight);
618     double imageRatio = ((double) iImageWidth) / ((double) iImageHeight);
619
620     if (thumbRatio < imageRatio)
621       iImageHeight = (int)(iThumbWidth / imageRatio);
622     else
623       iThumbWidth = (int)(iThumbHeight * imageRatio);
624
625     if (null==mediaTracker) {
626       if (DebugFile.trace) DebugFile.writeln("new java.awt.;Frame()");
627
628       try {
629         awtFrame = new Frame JavaDoc();
630       } catch (Exception JavaDoc e) { throw new InstantiationException JavaDoc("Cannot instantiate java.awt.Frame " + (e.getMessage()!=null ? e.getMessage() : "")); }
631
632       if (DebugFile.trace) DebugFile.writeln("new MediaTracker([Frame])");
633
634       mediaTracker = new MediaTracker JavaDoc(awtFrame);
635     } // fi (mediaTracker)
636

637     mediaTracker.addImage(oImg, 0);
638     mediaTracker.waitForID(0);
639
640     // draw original image to thumbnail image object and
641
// scale it to the new size on-the-fly
642
thumbImage = new BufferedImage JavaDoc(iThumbWidth, iThumbHeight, BufferedImage.TYPE_INT_RGB);
643
644     if (DebugFile.trace) DebugFile.writeln("java.awt.Graphics2D = thumbImage.createGraphics()");
645
646     graphics2D = thumbImage.createGraphics();
647     graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
648     graphics2D.drawImage(oImg, 0, 0, iThumbWidth, iThumbHeight, null);
649     graphics2D.dispose();
650
651     if (DebugFile.trace) DebugFile.writeln("com.sun.image.codec.jpeg.JPEGImageEncoder = JPEGCodec.createJPEGEncoder([OutputStream]);");
652
653     encoder = com.sun.image.codec.jpeg.JPEGCodec.createJPEGEncoder(outStr);
654     param = encoder.getDefaultJPEGEncodeParam(thumbImage);
655
656     fQuality = Math.max(0, Math.min(fQuality, 100));
657     if (fQuality>1)
658       param.setQuality(fQuality / 100.0f, false);
659     else
660       param.setQuality(fQuality, false);
661
662     encoder.setJPEGEncodeParam(param);
663
664     if (DebugFile.trace) DebugFile.writeln("JPEGImageEncoder.encode([BufferedImage]);");
665
666     encoder.encode(thumbImage);
667
668     thumbImage.flush();
669
670     mediaTracker.removeImage(oImg, 0);
671
672     if (DebugFile.trace) {
673       DebugFile.decIdent();
674       DebugFile.writeln("End Image.drawAWTImage()");
675     }
676   } // drawAWTImage()
677

678
679   // ----------------------------------------------------------
680

681   private void drawJAIImage(OutputStream JavaDoc outStr, int iThumbWidth, int iThumbHeight, float fQuality)
682     throws IOException JavaDoc, InterruptedException JavaDoc, NullPointerException JavaDoc, IllegalArgumentException JavaDoc {
683
684     com.sun.media.jai.codec.ImageDecoder oDecoder;
685     RenderedImage JavaDoc oRenderedImg;
686     javax.media.jai.PlanarImage oPlI;
687     javax.media.jai.PlanarImage oScI;
688     ParameterBlock JavaDoc oBlk;
689     com.sun.media.jai.codec.ImageEncoder oImgEnc;
690     String JavaDoc sInputURI;
691     InputStream JavaDoc oInputStream;
692     URL JavaDoc oURI;
693
694     if (DebugFile.trace) {
695       DebugFile.writeln("Begin Image.drawJAIImage([OutputStream], " + String.valueOf(iThumbWidth) + "," + String.valueOf(iThumbHeight) + "," + String.valueOf(fQuality) + ")");
696       DebugFile.incIdent();
697     }
698
699     sInputURI = getString(DB.path_image);
700
701     if (sInputURI.startsWith("http://") || sInputURI.startsWith("https://")) {
702
703       if (DebugFile.trace) DebugFile.writeln("new URL(" + sInputURI + ")");
704
705       oURI = new URL JavaDoc(sInputURI);
706       oInputStream = oURI.openStream();
707     }
708     else {
709       if (DebugFile.trace) DebugFile.writeln("new FileInputStream(" + sInputURI + ")");
710
711       try {
712         oInputStream = new FileInputStream JavaDoc(sInputURI);
713       } catch (FileNotFoundException JavaDoc fnf) {
714         if (DebugFile.trace) DebugFile.decIdent();
715         throw new FileNotFoundException JavaDoc(fnf.getMessage());
716       } catch (IOException JavaDoc ioe) {
717         if (DebugFile.trace) DebugFile.decIdent();
718         throw new IOException JavaDoc(ioe.getMessage());
719       }
720     }
721
722     oDecoder = com.sun.media.jai.codec.ImageCodec.createImageDecoder(getImageCodec(), oInputStream, null);
723
724     oRenderedImg = oDecoder.decodeAsRenderedImage();
725
726     if (getImageType().equals("gif")) {
727       // Increase color depth to 16M RGB
728
try {
729         javax.media.jai.ImageLayout layout = new javax.media.jai.ImageLayout();
730
731         ColorModel JavaDoc cm = new ComponentColorModel JavaDoc (ColorSpace.getInstance(ColorSpace.CS_sRGB),
732                                                  new int[] {8,8,8}, false, false,
733                                                  Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
734         layout.setColorModel(cm);
735         layout.setSampleModel(cm.createCompatibleSampleModel(oRenderedImg.getWidth(),oRenderedImg.getHeight()));
736         RenderingHints JavaDoc hints = new RenderingHints JavaDoc(javax.media.jai.JAI.KEY_IMAGE_LAYOUT, layout);
737         javax.media.jai.ParameterBlockJAI pb = new javax.media.jai.ParameterBlockJAI( "format" );
738         pb.addSource( oRenderedImg );
739         oRenderedImg = javax.media.jai.JAI.create( "format", pb, hints );
740       } catch (IllegalArgumentException JavaDoc iae) {
741         if (DebugFile.trace) DebugFile.writeln(iae.getMessage() + " " + oRenderedImg.getColorModel().getClass().getName() + " " + oRenderedImg.getSampleModel().getClass().getName());
742       }
743       // End increase color depth
744
} // gif
745

746     oPlI = javax.media.jai.PlanarImage.wrapRenderedImage(oRenderedImg);
747
748     int iImageWidth = oPlI.getWidth();
749     int iImageHeight = oPlI.getHeight();
750
751     if (DebugFile.trace) DebugFile.writeln("image width " + String.valueOf(iImageWidth));
752     if (DebugFile.trace) DebugFile.writeln("image height " + String.valueOf(iImageHeight));
753
754     float thumbRatio = ((float) iThumbWidth) / ((float) iThumbHeight);
755
756     if (DebugFile.trace) DebugFile.writeln("thumb ratio " + String.valueOf(thumbRatio));
757
758     float imageRatio = ((float) iImageWidth) / ((float) iImageHeight);
759
760     if (DebugFile.trace) DebugFile.writeln("image ratio " + String.valueOf(imageRatio));
761
762     if (thumbRatio < imageRatio)
763       iThumbHeight = (int)(iThumbWidth / imageRatio);
764     else
765       iThumbWidth = (int)(iThumbHeight * imageRatio);
766
767     float scaleW = ((float) iThumbWidth) / ((float) iImageWidth);
768
769     if (DebugFile.trace) DebugFile.writeln("scale width " + String.valueOf(scaleW));
770
771     float scaleH = ((float) iThumbHeight) / ((float) iImageHeight);
772
773     if (DebugFile.trace) DebugFile.writeln("scale height " + String.valueOf(scaleH));
774
775     oBlk = new ParameterBlock JavaDoc();
776
777     oBlk.addSource(oPlI);
778
779     oBlk.add(scaleW);
780     oBlk.add(scaleH);
781     oBlk.add(0.0f);
782     oBlk.add(0.0f);
783     oBlk.add(new javax.media.jai.InterpolationBilinear());
784
785     if (DebugFile.trace) DebugFile.writeln("JAI.create (\"scale\", [ParameterBlock], null)");
786
787     oScI = javax.media.jai.JAI.create("scale", oBlk, null); // scale image NOW !
788

789     if (DebugFile.trace) DebugFile.writeln("ImageCodec.createImageEncoder( \"jpeg\", [OutputStream], null )");
790
791     oImgEnc = com.sun.media.jai.codec.ImageCodec.createImageEncoder( "jpeg", outStr, null );
792
793     if (null==oImgEnc) {
794       oInputStream.close();
795       if (DebugFile.trace) DebugFile.decIdent();
796       throw new NullPointerException JavaDoc("Cannot create ImageEncoder for jpeg");
797     }
798     else {
799       if (DebugFile.trace) DebugFile.writeln("ImageEncoder.encode ([PlanarImage])");
800
801       oImgEnc.encode( oScI ); // write encoded data to given output stream
802

803       oImgEnc =null;
804
805       oInputStream.close();
806     }
807
808     if (DebugFile.trace) {
809       DebugFile.decIdent();
810       DebugFile.writeln("End Image.drawJAIImage()");
811     }
812   } // drawJAIImage
813

814   // ----------------------------------------------------------
815
/**
816    * <p>Resample image.</p>
817    * @param iThumbWidth Desired width
818    * @param iThumbHeight Desired height
819    * @param fQuality JPG Quality [1..100]
820    * @return Byte array holding the generated JPEG image
821    * @throws NullPointerException
822    * @throws IOException
823    * @throws InterruptedException
824    * @throws InstantiationException
825    */

826   public byte[] createThumbBitmap(int iThumbWidth, int iThumbHeight, float fQuality)
827     throws NullPointerException JavaDoc, IOException JavaDoc, InterruptedException JavaDoc, InstantiationException JavaDoc {
828
829     if (DebugFile.trace) {
830       DebugFile.writeln("Begin Image.createThumbBitmap(" + String.valueOf(iThumbWidth) + "," + String.valueOf(iThumbHeight) + "," + String.valueOf(fQuality) + ")");
831       DebugFile.incIdent();
832     }
833
834     ByteArrayOutputStream JavaDoc outStr = new ByteArrayOutputStream JavaDoc(iThumbWidth*iThumbHeight*3+1024);
835
836     if (USE_AWT==iImagingLibrary)
837       drawAWTImage (outStr, iThumbWidth, iThumbHeight, fQuality);
838     else
839       drawJAIImage (outStr, iThumbWidth, iThumbHeight, fQuality);
840
841     if (DebugFile.trace) {
842       DebugFile.decIdent();
843       DebugFile.writeln("End Image.createThumbBitmap()");
844     }
845
846     return outStr.toByteArray();
847   } // createThumbBitmap()
848

849   // ----------------------------------------------------------
850
/**
851    * <p>Resample image.</p>
852    * @param sOutputPath File path where generated JPEG shall be saved.
853    * @param iThumbWidth Desired width
854    * @param iThumbHeight Desired height
855    * @param fQuality JPG Quality [1..100]
856    * @throws NullPointerException
857    * @throws IOException
858    * @throws InstantiationException
859    * @throws InterruptedException
860    * @throws InstantiationException
861    */

862
863   public void createThumbFile(String JavaDoc sOutputPath, int iThumbWidth, int iThumbHeight, float fQuality)
864     throws NullPointerException JavaDoc, InterruptedException JavaDoc, IOException JavaDoc, InstantiationException JavaDoc {
865
866     if (DebugFile.trace) {
867       DebugFile.writeln("Begin Image.createThumbFile(" + sOutputPath + "," + String.valueOf(iThumbWidth) + "," + String.valueOf(iThumbHeight) + "," + String.valueOf(fQuality) + ")");
868       DebugFile.incIdent();
869     }
870
871     FileOutputStream JavaDoc outStr = new FileOutputStream JavaDoc(sOutputPath);
872
873     if (USE_AWT==iImagingLibrary)
874       drawAWTImage (outStr, iThumbWidth, iThumbHeight, fQuality);
875     else
876       drawJAIImage (outStr, iThumbWidth, iThumbHeight, fQuality);
877
878     outStr.close();
879     outStr=null;
880
881     if (DebugFile.trace) {
882       DebugFile.decIdent();
883       DebugFile.writeln("End Image.createThumbFile()");
884     }
885   } // createThumbFile()
886

887   // ----------------------------------------------------------
888

889   /**
890    * <p>Encode Image and write it to an OutputStream</p>
891    * @param oOut OutputStream
892    * @throws NullPointerException If underlying java.awt.Image object is <b>null</b>
893    * @throws IOException
894    * @throws InstantiationException
895    * @throws InterruptedException
896    */

897   public void write(OutputStream JavaDoc oOut)
898     throws NullPointerException JavaDoc,IOException JavaDoc,InstantiationException JavaDoc,InterruptedException JavaDoc {
899
900     if (DebugFile.trace) {
901       DebugFile.writeln("Begin Image.write([OutputStream])");
902       DebugFile.incIdent();
903     }
904
905     if (null==oImg) {
906       if (DebugFile.trace) DebugFile.incIdent();
907       throw new NullPointerException JavaDoc("java.awt.Image is null");
908     }
909
910     com.sun.media.jai.codec.ImageEncoder oEnc = com.sun.media.jai.codec.ImageCodec.createImageEncoder(getImageCodec(), oOut, null);
911
912     if (null==oEnc) {
913       if (DebugFile.trace) DebugFile.incIdent();
914
915       throw new InstantiationException JavaDoc("ImageCodec.createImageEncoder("+getImageCodec()+")");
916     }
917     if (USE_JAI==iImagingLibrary) {
918
919       RenderedImage JavaDoc oRImg = javax.media.jai.JAI.create("awtimage", oImg);
920
921       if (null==oEnc) {
922         if (DebugFile.trace) DebugFile.incIdent();
923         throw new InstantiationException JavaDoc("JAI.create(awtimage, "+oImg.getClass().getName()+")");
924       }
925
926       oEnc.encode(oRImg);
927     }
928     else {
929       int iImageWidth = oImg.getWidth(null);
930       int iImageHeight = oImg.getHeight(null);
931
932       if (null==mediaTracker) {
933         if (DebugFile.trace) DebugFile.writeln("new java.awt.Frame()");
934
935         Frame JavaDoc awtFrame = null;
936         try {
937           awtFrame = new Frame JavaDoc();
938         } catch (Exception JavaDoc e) { throw new InstantiationException JavaDoc("Cannot instantiate java.awt.Frame " + (e.getMessage()!=null ? e.getMessage() : "")); }
939
940         if (DebugFile.trace) DebugFile.writeln("new MediaTracker([Frame])");
941
942         mediaTracker = new MediaTracker JavaDoc(awtFrame);
943       } // fi (mediaTracker)
944

945       mediaTracker.addImage(oImg, 0);
946       mediaTracker.waitForID(0);
947
948       BufferedImage JavaDoc oBImg = new BufferedImage JavaDoc(iImageWidth, iImageHeight, BufferedImage.TYPE_INT_RGB);
949
950       if (DebugFile.trace) DebugFile.writeln("java.awt.Graphics2D = thumbImage.createGraphics()");
951
952       Graphics2D JavaDoc graphics2D = oBImg.createGraphics();
953       graphics2D.drawImage(oImg, 0, 0, iImageWidth, iImageHeight, null);
954       graphics2D.dispose();
955
956       oEnc.encode(oBImg);
957
958       mediaTracker.removeImage(oImg,0);
959     }
960
961     if (DebugFile.trace) {
962       DebugFile.decIdent();
963       DebugFile.writeln("End Image.write([OutputStream])");
964     }
965   }
966
967   // ----------------------------------------------------------
968

969   /**
970    * <p>Get a transparent GIF image that can be served throught a JSP page</p>
971    * Use code like
972    * response.setContentType("image/gif");
973    * OutputStream oOut = response.getOutputStream();
974    * oOut.write(Image.blankGIF());
975    * oOut.flush();
976    * @since 3.0
977    * @return byte[]
978    */

979   public static byte[] blankGIF() {
980     return Base64Decoder.decodeToBytes("R0lGODlhAQABAJEAAAAAAP///////wAAACH5BAEAAAIALAAAAAABAAEAAAICVAEAOw==");
981   }
982
983
984   // **********************************************************
985
// Static Methods
986

987   private static void printUsage() {
988      System.out.println("Usage:");
989      System.out.println("com.knowgate.hipergate.Image [jai|awt] thumbnail path_original path_new_thumbnail int_thumb_width int_thumb_height float_quality");
990      System.out.println("Options:");
991      System.out.println("jai -> Use SUN Java Advanced Imaging (requires SUN's libraries");
992      System.out.println("awt -> Use Abstract Windowing Toolkit (requires X-Windows or Win32)");
993      System.out.println("path_original -> Full path to original .GIF or .JPEG image");
994      System.out.println("path_new_thumbnail -> Full path to generated thumbnail");
995      System.out.println("int_thumb_width -> Thumbnail width");
996      System.out.println("int_thumb_height -> Thumbnail height");
997      System.out.println("float_quality -> JPEG quality for thumbnail [0..100]");
998   }
999
1000  /**
1001   * <p>Image command line interface</p>
1002   * @param argv [jai|awt] thumbnail <i>path_original</i> <i>path_new_thumbnail</i> <i>int_thumb_width</i> <i>int_thumb_height</i> <i>float_quality</i><br>
1003   * Options:<br>
1004   * jai -> Use SUN Java Advanced Imaging (requires SUN's libraries<br>
1005   * awt -> Use Abstract Windowing Toolkit (requires X-Windows or Win32)<br>
1006   * path_original -> Full path to original .GIF or .JPEG image<br>
1007   * path_new_thumbnail -> Full path to generated thumbnail<br>
1008   * int_thumb_width -> Thumbnail width");
1009   * int_thumb_height -> Thumbnail height<br>
1010   * float_quality -> JPEG quality for thumbnail [0..100]<br>
1011   * @throws NumberFormatException
1012   * @throws InstantiationException
1013   * @throws InterruptedException
1014   * @throws FileNotFoundException
1015   * @throws IOException
1016   */

1017  public static void main(String JavaDoc[] argv)
1018    throws NumberFormatException JavaDoc, InstantiationException JavaDoc, InterruptedException JavaDoc,
1019           FileNotFoundException JavaDoc, IOException JavaDoc {
1020
1021    DBBind oDBB = new DBBind();
1022
1023    Image oImg;
1024
1025    if (argv.length<6 || argv.length>7) {
1026      System.out.println("");
1027      System.out.println("Invalid number of parameters");
1028      printUsage();
1029    }
1030    else if (!argv[0].equalsIgnoreCase("jai") && !argv[0].equalsIgnoreCase("awt")
1031          && !argv[0].equalsIgnoreCase("thumbnail")) {
1032      System.out.println("");
1033      System.out.println("Parameter 1 must be jai,awt or thumbnail");
1034      printUsage();
1035    }
1036    else if ((argv[0].equalsIgnoreCase("jai") || argv[0].equalsIgnoreCase("awt"))
1037         && !argv[1].equalsIgnoreCase("thumbnail")) {
1038      System.out.println("");
1039      System.out.println("Parameter 2 must be thumbnail");
1040      printUsage();
1041    }
1042    else {
1043      if (argv[0].equalsIgnoreCase("jai")) {
1044        oImg = new Image(USE_JAI);
1045        oImg.put(DB.path_image, argv[2]);
1046        oImg.createThumbFile(argv[3], Integer.parseInt(argv[4]), Integer.parseInt(argv[5]), Float.parseFloat(argv[6]));
1047        oImg = null;
1048      }
1049      else if (argv[0].equalsIgnoreCase("awt")) {
1050        oImg = new Image(USE_AWT);
1051        oImg.put(DB.path_image, argv[2]);
1052        oImg.createThumbFile(argv[3], Integer.parseInt(argv[4]), Integer.parseInt(argv[5]), Float.parseFloat(argv[6]));
1053        oImg = null;
1054      }
1055      else {
1056        oImg = new Image(USE_AWT);
1057        oImg.put(DB.path_image, argv[1]);
1058        oImg.createThumbFile(argv[2], Integer.parseInt(argv[3]), Integer.parseInt(argv[4]), Float.parseFloat(argv[5]));
1059        oImg = null;
1060      }
1061    }
1062    oDBB.close();
1063
1064    if (argv.length==6)
1065      System.out.println("Thumbnail " + argv[2] + " successfully created");
1066    else
1067      System.out.println("Thumbnail " + argv[3] + " successfully created");
1068
1069  } // main
1070

1071  // **********************************************************
1072
// Public Constants
1073

1074  public static final int USE_AWT = 0;
1075  public static final int USE_JAI = 1;
1076
1077  public static final short ClassId = 13;
1078
1079} // Image
1080
Popular Tags