ImageUtils.java

00001 package edu.stanford.hci.r3.util.graphics;
00002 
00003 import java.awt.Dimension;
00004 import java.awt.Graphics2D;
00005 import java.awt.image.BufferedImage;
00006 import java.awt.image.RenderedImage;
00007 import java.io.BufferedOutputStream;
00008 import java.io.File;
00009 import java.io.FileNotFoundException;
00010 import java.io.FileOutputStream;
00011 import java.io.IOException;
00012 import java.sql.Timestamp;
00013 
00014 import javax.imageio.ImageIO;
00015 import javax.media.jai.PlanarImage;
00016 
00017 import com.drew.imaging.jpeg.JpegMetadataReader;
00018 import com.drew.imaging.jpeg.JpegProcessingException;
00019 import com.drew.metadata.Directory;
00020 import com.drew.metadata.Metadata;
00021 import com.drew.metadata.MetadataException;
00022 import com.drew.metadata.exif.ExifDirectory;
00023 import com.drew.metadata.jpeg.JpegDirectory;
00024 import com.sun.image.codec.jpeg.ImageFormatException;
00025 import com.sun.image.codec.jpeg.JPEGCodec;
00026 import com.sun.image.codec.jpeg.JPEGEncodeParam;
00027 import com.sun.image.codec.jpeg.JPEGImageEncoder;
00028 
00037 public class ImageUtils {
00038 
00044         public static BufferedImage createWritableBuffer(int width, int height) {
00045                 return new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
00046         }
00047 
00054         public static long getTimeFromString(String timestampString) {
00055                 // Timestamp can parse strings like: yyyy-mm-dd hh:mm:ss.fffffffff
00056                 // so, we transform the string
00057 
00058                 if (timestampString == null) {
00059                         return new Timestamp(0).getTime();
00060                 }
00061                 if (timestampString.trim().equals("")) {
00062                         return new Timestamp(0).getTime();
00063                 }
00064 
00065                 // convert all colons before space to dashes
00066                 String ymd = timestampString.substring(0, 11);
00067                 ymd = ymd.replaceAll(":", "-");
00068 
00069                 // add .0 to the end
00070                 final String hms = timestampString.substring(11) + ".000000000";
00071 
00072                 // create a new timestamp
00073                 final String ts = ymd + hms;
00074 
00075                 return Timestamp.valueOf(ts).getTime();
00076         }
00077 
00081         public static boolean isJPEGFile(File imageFile) {
00082                 final String fileName = imageFile.getName().toLowerCase();
00083                 if (fileName.endsWith(".jpeg") || fileName.endsWith(".jpg")) {
00084                         return true;
00085                 } else {
00086                         return false;
00087                 }
00088         }
00089 
00096         public static String readCaptureDateFromEXIF(File photoFile) {
00097                 Metadata metadata = null;
00098                 try {
00099                         metadata = JpegMetadataReader.readMetadata(photoFile);
00100                 } catch (JpegProcessingException e) {
00101                         // XXX: suppress this, as we do not checking JPEGness before call
00102                         // e.printStackTrace();
00103                         return null;
00104                 }
00105 
00106                 if (metadata == null) {
00107                         return null;
00108                 }
00109                 Directory exifDirectory = metadata.getDirectory(ExifDirectory.class);
00110 
00111                 // Time Captured
00112                 // System.out.println(exifDirectory.getString(ExifDirectory.TAG_DATETIME_DIGITIZED));
00113 
00114                 // Time Uploaded
00115                 // System.out.println(exifDirectory.getString(ExifDirectory.TAG_DATETIME));
00116 
00117                 // Time Captured
00118                 String ts = exifDirectory.getString(ExifDirectory.TAG_DATETIME_ORIGINAL);
00119                 return ts;
00120         }
00121 
00126         public static BufferedImage readImage(File source) {
00127                 return JAIUtils.readJPEG(source).getAsBufferedImage();
00128         }
00129 
00137         public static Dimension readSize(File imageFile) {
00138                 if (isJPEGFile(imageFile)) {
00139                         try {
00140                                 final Metadata metadata = JpegMetadataReader.readMetadata(imageFile);
00141                                 final Directory jpegDirectory = metadata.getDirectory(JpegDirectory.class);
00142                                 return new Dimension(jpegDirectory.getInt(JpegDirectory.TAG_JPEG_IMAGE_WIDTH),
00143                                                 jpegDirectory.getInt(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT));
00144                         } catch (JpegProcessingException e) {
00145                                 // fall through
00146                         } catch (MetadataException e) {
00147                                 // fall through
00148                         }
00149                 }
00150                 return readSizeByLoading(imageFile);
00151         }
00152 
00161         public static Dimension readSizeByLoading(File imageFile) {
00162                 final PlanarImage planarImage = ImageCache.getInstance().getPlanarImage(imageFile);
00163                 return new Dimension(planarImage.getWidth(), planarImage.getHeight());
00164         }
00165 
00177         public static long readTimeFrom(File photo) {
00178                 String ts = readCaptureDateFromEXIF(photo);
00179                 if (ts == null) {
00180                         return photo.lastModified();
00181                 } else {
00182                         return getTimeFromString(ts);
00183                 }
00184         }
00185 
00196         public static BufferedImage scaleImage(BufferedImage src, float sX, float sY) {
00197                 System.err
00198                                 .println("Warning: ImageUtils::scaleImage is a low quality scale. Please use ImageUtils::scaleImageIteratively.");
00199 
00200                 final int width = (int) (src.getWidth() * sX + 0.5);
00201                 final int height = (int) (src.getHeight() * sY + 0.5);
00202                 final BufferedImage scaledImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
00203                 final Graphics2D gScaledImg = scaledImg.createGraphics();
00204                 gScaledImg.setRenderingHints(GraphicsUtils.getBestRenderingHints());
00205                 gScaledImg.drawImage(src, 0, 0, width, height, null);
00206                 return scaledImg;
00207         }
00208 
00209         public static BufferedImage scaleImageToFit(BufferedImage src, int width, int height) {
00210                 return scaleImageToSize(src, width, height, true);
00211         }
00212 
00213         public static BufferedImage scaleImageToSize(BufferedImage src, int targetWidth,
00214                         int targetHeight, boolean maintainAspectRatio) {
00215                 // old width and height
00216                 final int width = src.getWidth();
00217                 final int height = src.getHeight();
00218 
00219                 // the scaling factor
00220                 final float testScaleFactorX = (float) targetWidth / (float) width;
00221                 final float testScaleFactorY = (float) targetHeight / (float) height;
00222 
00223                 // SystemUtilities.println(testScaleFactorX + " " + testScaleFactorY);
00224 
00225                 float scaleFactorX = 0;
00226                 float scaleFactorY = 0;
00227 
00228                 // if maintaining Aspect Ratio, add some padding either on
00229                 // the top/bottom or the left/right
00230                 if (maintainAspectRatio) {
00231                         float min = Math.min(testScaleFactorX, testScaleFactorY);
00232                         scaleFactorX = min;
00233                         scaleFactorY = min;
00234                 } else {
00235                         scaleFactorX = testScaleFactorX;
00236                         scaleFactorY = testScaleFactorY;
00237                 }
00238 
00239                 // never scale up a photo, or scale it to the same size.. :)
00240                 if (scaleFactorX >= 1 || scaleFactorY >= 1) {
00241                         return src;
00242                 }
00243 
00244                 return scaleImage(src, scaleFactorX, scaleFactorY);
00245         }
00246 
00251         public static void writeImageToJPEG(BufferedImage bufferedImage, File file) {
00252                 writeImageToJPEG(bufferedImage, 100, file);
00253         }
00254 
00267         public static void writeImageToJPEG(BufferedImage buffImage, int quality, File outputFile) {
00268                 BufferedOutputStream out;
00269 
00270                 // bounds check on quality parameter
00271                 if (quality < 0) {
00272                         quality = 0;
00273                 }
00274                 if (quality > 100) {
00275                         quality = 100;
00276                 }
00277 
00278                 try {
00279                         out = new BufferedOutputStream(new FileOutputStream(outputFile));
00280                         final JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
00281                         final JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(buffImage);
00282                         quality = Math.max(0, Math.min(quality, 100));
00283                         param.setQuality(quality / 100.0f, false);
00284                         encoder.setJPEGEncodeParam(param);
00285                         encoder.encode(buffImage);
00286                         out.close();
00287                 } catch (FileNotFoundException e) {
00288                         e.printStackTrace();
00289                 } catch (ImageFormatException e) {
00290                         e.printStackTrace();
00291                 } catch (IOException e) {
00292                         e.printStackTrace();
00293                 }
00294         }
00295 
00300         public static void writeImageToPNG(RenderedImage rImage, File outputFile) {
00301                 try {
00302                         ImageIO.write(rImage, "png", outputFile);
00303                 } catch (IOException e) {
00304                         e.printStackTrace();
00305                 }
00306         }
00307 
00308 }

Generated on Sat Apr 14 18:21:35 2007 for R3 Paper Toolkit by  doxygen 1.4.7