+ /**
+ * ImageFile is a thin wrapper around a file that contains an
+ * image. It uses ImageMagick to retreive information about the
+ * image. It can also scale images using ImageMagick. Intended for
+ * use in the ImageMagickImageProcessor class.
+ */
+ static class ImageFile {
+ /**
+ * path to the file represented by this class
+ */
+ File file;
+ /**
+ * whether the file must be deleted on cleanup
+ */
+ boolean fileIsTemp = false;
+ /**
+ * image information is stored here to avoid multiple costly calls to
+ * "identify"
+ */
+ int width;
+ int height;
+ int fileSize;
+
+ /**
+ * Image type as returned by identify %m : "PNG", "GIF", ...
+ */
+ String type;
+ /**
+ * number of scenes in image >1 (typically animated gif)
+ */
+ boolean isAnimation;
+
+ /**
+ * Empty constructor automatically creates a temporary file
+ * that will later hold an image
+ */
+ ImageFile() throws IOException {
+ file = File.createTempFile("mirimage", "");
+ fileIsTemp = true;
+ }
+
+ /**
+ * if the file doesn't already have an image in it
+ * we don't want to read its information
+ */
+ ImageFile(File file, boolean doReadInfo) throws IOException {
+ this.file = file;
+ if (doReadInfo) {
+ readInfo();
+ }
+ }
+
+ ImageFile(File file) throws IOException {
+ this(file, true);
+ }
+
+ /**
+ * delete temporary files
+ */
+ public void cleanup() {
+ logger.debug("ImageFile.cleanup()");
+ if (fileIsTemp) {
+ logger.debug("deleting:" + file);
+ file.delete();
+ file = null;
+ fileIsTemp = false;
+ }
+ }
+
+ void debugOutput() {
+ logger.debug(" filename:" + file +
+ " Info:" +
+ " width:" + width +
+ " height:" + height +
+ " type:" + type +
+ " isAnimation:" + isAnimation);
+ }
+
+ private void checkFile() throws IOException {
+ if (file == null || !file.exists()) {
+ String message = "ImageFile.checkFile file \"" + file +
+ "\" does not exist";
+ logger.error(message);
+ throw new IOException(message);
+ }
+ }
+
+ /**
+ * Uses the imagemagick "identify" command to retreive image information
+ */
+ public void readInfo() throws IOException {
+ checkFile();
+ String infoString = ShellRoutines.execIntoString
+ (getImageMagickPath() +
+ "identify " + "-format \"%w %h %m %n %b \" " +
+ file.getAbsolutePath()); // extra space, for multiframe (animations)
+ StringTokenizer st = new StringTokenizer(infoString);
+ width = Integer.parseInt(st.nextToken());
+ height = Integer.parseInt(st.nextToken());
+ type = st.nextToken();
+ isAnimation = Integer.parseInt(st.nextToken()) > 1;
+ // yoss: different versions of ImageMagick produce different formatted output file sizes
+ // for example, Version: ImageMagick 6.2.4 (Ubuntu Dapper 6.06) produces a byte value, i.e. 67013
+ // Version: ImageMagick 6.0.6 (Debian Sarge) produces output like 67kb or 500mb.
+ // Trying to do an int.parse in Sarge fails for obvious reasons.
+ /*String sFileSize = st.nextToken();
+ if (sFileSize.endsWith("kb") || sFileSize.endsWith("Kb") || sFileSize.endsWith("KB") || sFileSize.endsWith("kB")){
+ sFileSize = sFileSize.substring(0, sFileSize.length() - 2);
+ fileSize = 1024 * Integer.parseInt(sFileSize);
+ } else if (sFileSize.endsWith("mb") || sFileSize.endsWith("Mb") || sFileSize.endsWith("MB") || sFileSize.endsWith("mB")){
+ sFileSize = sFileSize.substring(0, sFileSize.length() - 2);
+ fileSize = 1048576 * Integer.parseInt(sFileSize);
+ } else {
+ fileSize = Integer.parseInt(sFileSize);
+ }*/
+ fileSize = (int)file.length();
+ }
+
+ public ImageFile scale(float aScalingFactor) throws IOException {
+ logger.debug("ImageFile.scale");
+ checkFile();
+ ImageFile result = new ImageFile();
+ String command = getImageMagickPath() + "convert " +
+ file.getAbsolutePath() + " " +
+ "-scale " +
+ Float.toString(aScalingFactor * 100) + "% " +
+ result.file.getAbsolutePath();
+ logger.debug("ImageFile.scale:command:" + command);
+ ShellRoutines.simpleExec(command);
+ result.readInfo();
+ return result;
+ }
+ }
+