From d06e23e638f2538f263af76bd32da6b140f20ac6 Mon Sep 17 00:00:00 2001 From: ngu Date: Sun, 27 May 2007 12:17:10 +0000 Subject: [PATCH] fixing scaling images -> nullpointer, patch by yossarian --- .../mir/media/image/ImageMagickImageProcessor.java | 771 ++++++++++----------- source/mir/media/image/ImageProcessor.java | 172 +++-- .../mircoders/media/MediaHandlerImagesExtern.java | 364 +++++----- .../media/MediaHandlerImagesExternScaling.java | 449 ++++++------ 4 files changed, 868 insertions(+), 888 deletions(-) diff --git a/source/mir/media/image/ImageMagickImageProcessor.java b/source/mir/media/image/ImageMagickImageProcessor.java index bb9a3dcc..460f76f2 100755 --- a/source/mir/media/image/ImageMagickImageProcessor.java +++ b/source/mir/media/image/ImageMagickImageProcessor.java @@ -1,404 +1,367 @@ -/* - * Copyright (C) 2005 The Mir-coders group - * - * This file is part of Mir. - * - * Mir is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Mir is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mir; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with any library licensed under the Apache Software License. - * You must obey the GNU General Public License in all respects for all of the code used - * other than the above mentioned libraries. If you modify this file, you may extend this - * exception to your version of the file, but you are not obligated to do so. - * If you do not wish to do so, delete this exception statement from your version. - */ -package mir.media.image; - -import mir.log.LoggerWrapper; -import mir.media.MediaExc; -import mir.media.MediaFailure; -import mir.util.StreamCopier; -import mir.util.ShellRoutines; -import mir.config.MirPropertiesConfiguration; - -import java.io.BufferedOutputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.StringTokenizer; - - -/** - * Image processing by calling the ImageMagick command line progrmas - * "convert" and "identify". The main task of this class is to scale - * images. The path to ImageMagick commandline programs can be - * specified in the coonfiguration file. - * - * @author , the Mir-coders group - */ -public class ImageMagickImageProcessor implements ImageProcessor { - protected static MirPropertiesConfiguration configuration = - MirPropertiesConfiguration.instance(); - static final LoggerWrapper logger = - new LoggerWrapper("media.image.imagemagick"); - - private ImageFile sourceImage; - private ImageFile scaledImage; - - /** - * 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; - } - } - - public ImageMagickImageProcessor(InputStream inputImageStream) - throws IOException { - logger.debug("ImageMagickImageProcessor(stream)"); - sourceImage = new ImageFile(); - // copy stream into temporary file - - FileOutputStream outputStream = new FileOutputStream(sourceImage.file); - try { - StreamCopier.copy(inputImageStream, outputStream); - } - finally { - outputStream.close(); - } - sourceImage.readInfo(); - sourceImage.debugOutput(); - } - - - public ImageMagickImageProcessor(File aFile) throws IOException { - logger.debug("ImageMagickImageProcessor(file)"); - sourceImage = new ImageFile(aFile); - sourceImage.debugOutput(); - } - - /** - * Deletes temporary files - */ - public void cleanup() { - logger.debug("ImageMagickImageProcessor.cleanup()"); - sourceImage.cleanup(); - scaledImage.cleanup(); - } - - /** - * Path to ImageMagick commandline programs - */ - private static String getImageMagickPath() { - String result = configuration.getString("Producer.Image.ImageMagickPath"); - // we want the path to finish by "/", so add it if it's missing - if (result.length() != 0 && !result.endsWith("/")) { - result = result.concat("/"); - } - logger.debug("getImageMagickPath:" + result); - return result; - } - - public void descaleImage(int aMaxSize) throws MediaExc { - descaleImage(aMaxSize, 0); - } - - public void descaleImage(int aMaxSize, float aMinDescale) throws MediaExc { - descaleImage(aMaxSize, aMaxSize, aMinDescale, 0); - } - - public void descaleImage(int aMaxSize, int aMinResize) throws MediaExc { - descaleImage(aMaxSize, aMaxSize, 0, aMinResize); - } - - public void descaleImage(int aMaxSize, float aMinDescale, int aMinResize) - throws MediaExc { - descaleImage(aMaxSize, aMaxSize, aMinDescale, aMinResize); - } - - /** - * {@inheritDoc} - */ - public void descaleImage(int aMaxWidth, int aMaxHeight, - float aMinDescale, int aMinResize) throws MediaExc { - float scale; - logger.debug("descaleImage:" + - " aMaxWidth:" + aMaxWidth + - ", aMaxHeight:" + aMaxHeight + - ", aMinDescale:" + aMinDescale + - ", aMinResize:" + aMinResize); - if ((aMaxWidth > 0 && getWidth() > aMaxWidth + aMinResize - 1) || - (aMaxHeight > 0 && getHeight() > aMaxHeight + aMinResize - 1)) { - logger.debug("descaleImage: image needs scaling"); - - scale = 1; - - if (aMaxWidth > 0 && getWidth() > aMaxWidth) { - scale = Math.min(scale, (float) aMaxWidth / (float) getWidth()); - } - if (aMaxHeight > 0 && getHeight() > aMaxHeight) { - scale = Math.min(scale, (float) aMaxHeight / (float) getHeight()); - } - - if (1 - scale > aMinDescale) { - scaleImage(scale); - - return; - } - } - logger.debug("descaleImage: image size is ok, not scaling image"); - try { - scaledImage = new ImageFile(sourceImage.file); - } - catch (IOException e) { - throw new MediaExc(e.toString()); - } - } - - - /** - * Scales image by a factor using the convert ImageMagick command - */ - public void scaleImage(float aScalingFactor) - throws MediaExc { - logger.debug("scaleImage:" + aScalingFactor); - try { - // first cleanup previous temp scaledimage file if necesary - if (scaledImage != null) { - scaledImage.cleanup(); - } - // now create temp file and execute convert - scaledImage = sourceImage.scale(aScalingFactor); - } - catch (Exception e) { - throw new MediaExc(e.toString()); - } - logger.debug(" scaledImage:"); - scaledImage.debugOutput(); - } - - public int getWidth() { - return sourceImage.width; - } - - public int getHeight() { - return sourceImage.height; - } - - public int getSourceFileSize() { - return sourceImage.fileSize; - } - - public int getScaledFileSize() { - return scaledImage.fileSize; - } - - public int getScaledWidth() { - return scaledImage.width; - } - - public int getScaledHeight() { - return scaledImage.height; - } - - public void writeScaledData(OutputStream aStream, String anImageType) - throws MediaExc { - // we can't asume that requested "anImageType" is the same as the - // scaled image type, so we have to convert - try { - // if image is an animation and target type doesn't support - // animations, then just use first frame - String frame = ""; - scaledImage.debugOutput(); - if (scaledImage.isAnimation && !anImageType.equals("GIF")) { - frame = "[0]"; - } - // ImageMagick "convert" into temp file - File temp = File.createTempFile("mirimage", ""); - String command = getImageMagickPath() + "convert " + - scaledImage.file.getAbsolutePath() + frame + " " + - anImageType + ":" + temp.getAbsolutePath(); - logger.debug("writeScaledData command:" + command); - ShellRoutines.simpleExec(command); - // copy temp file into stream - StreamCopier.copy(new FileInputStream(temp), aStream); - temp.delete(); - } - catch (Exception e) { - throw new MediaExc(e.toString()); - } - } - - public byte[] getScaledData(String anImageType) throws MediaExc { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - writeScaledData(outputStream, anImageType); - return outputStream.toByteArray(); - } - - public void writeScaledData(File aFile, String anImageType) throws MediaExc { - try { - OutputStream stream = new BufferedOutputStream(new FileOutputStream(aFile), 8192); - - try { - writeScaledData(stream, anImageType); - } - finally { - try { - stream.close(); - } - catch (Throwable t) { - logger.debug("Unable to close stream when writing scaled data."); - } - } - } - catch (FileNotFoundException f) { - throw new MediaFailure(f); - } - catch (Exception e) { - logger.debug("Exception caught while trying to write scaled data: " + e.toString()); - } - } -} +/* + * Copyright (C) 2005 The Mir-coders group + * + * This file is part of Mir. + * + * Mir is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Mir is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mir; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, The Mir-coders gives permission to link + * the code of this program with any library licensed under the Apache Software License. + * You must obey the GNU General Public License in all respects for all of the code used + * other than the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. + * If you do not wish to do so, delete this exception statement from your version. + */ +package mir.media.image; + +import mir.config.MirPropertiesConfiguration; +import mir.log.LoggerWrapper; +import mir.media.MediaExc; +import mir.util.ShellRoutines; +import mir.util.StreamCopier; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.StringTokenizer; + + +/** + * Image processing by calling the ImageMagick command line progrmas + * "convert" and "identify". The main task of this class is to scale + * images. The path to ImageMagick commandline programs can be + * specified in the configuration file. + * + * @author , the Mir-coders group + */ +public class ImageMagickImageProcessor implements ImageProcessor { + protected static MirPropertiesConfiguration configuration = + MirPropertiesConfiguration.instance(); + static final LoggerWrapper logger = + new LoggerWrapper("media.image.imagemagick"); + + private ImageFile sourceImage; + private ImageFile scaledImage; + + public ImageMagickImageProcessor(InputStream inputImageStream) + throws IOException { + logger.debug("ImageMagickImageProcessor(stream)"); + sourceImage = new ImageFile(); + // copy stream into temporary file + + FileOutputStream outputStream = new FileOutputStream(sourceImage.file); + try { + StreamCopier.copy(inputImageStream, outputStream); + } + finally { + outputStream.close(); + } + sourceImage.readInfo(); + sourceImage.debugOutput(); + } + + + public ImageMagickImageProcessor(File aFile) throws IOException { + logger.debug("ImageMagickImageProcessor(file)"); + sourceImage = new ImageFile(aFile); + sourceImage.debugOutput(); + } + + /** + * Deletes temporary files + */ + public void cleanup() { + logger.debug("ImageMagickImageProcessor.cleanup()"); + sourceImage.cleanup(); + scaledImage.cleanup(); + } + + /** + * Path to ImageMagick commandline programs + */ + private static String getImageMagickPath() { + String result = configuration.getString("Producer.Image.ImageMagickPath"); + // we want the path to finish by "/", so add it if it's missing + if (result.length() != 0 && !result.endsWith("/")) { + result = result.concat("/"); + } + logger.debug("getImageMagickPath:" + result); + return result; + } + + public void descaleImage(int aMaxSize) throws MediaExc { + descaleImage(aMaxSize, 0); + } + + public void descaleImage(int aMaxSize, float aMinDescale) throws MediaExc { + descaleImage(aMaxSize, aMaxSize, aMinDescale, 0); + } + + public void descaleImage(int aMaxSize, int aMinResize) throws MediaExc { + descaleImage(aMaxSize, aMaxSize, 0, aMinResize); + } + + public void descaleImage(int aMaxSize, float aMinDescale, int aMinResize) + throws MediaExc { + descaleImage(aMaxSize, aMaxSize, aMinDescale, aMinResize); + } + + /** + * {@inheritDoc} + */ + public void descaleImage(int aMaxWidth, int aMaxHeight, + float aMinDescale, int aMinResize) throws MediaExc { + float scale; + logger.debug("descaleImage:" + + " aMaxWidth:" + aMaxWidth + + ", aMaxHeight:" + aMaxHeight + + ", aMinDescale:" + aMinDescale + + ", aMinResize:" + aMinResize); + if ((aMaxWidth > 0 && getWidth() > aMaxWidth + aMinResize - 1) || + (aMaxHeight > 0 && getHeight() > aMaxHeight + aMinResize - 1)) { + logger.debug("descaleImage: image needs scaling"); + + scale = 1; + + if (aMaxWidth > 0 && getWidth() > aMaxWidth) { + scale = Math.min(scale, (float) aMaxWidth / (float) getWidth()); + } + if (aMaxHeight > 0 && getHeight() > aMaxHeight) { + scale = Math.min(scale, (float) aMaxHeight / (float) getHeight()); + } + + if (1 - scale > aMinDescale) { + scaleImage(scale); + + return; + } + } + + // the image didn't need to be scaled: scaledImage = original image + try { + scaledImage = new ImageFile(sourceImage.file); + } + catch (IOException e) { + throw new MediaExc(e.toString()); + } + + } + + + /** + * Scales image by a factor using the convert ImageMagick command + */ + public void scaleImage(float aScalingFactor) throws MediaExc { + logger.debug("scaleImage:" + aScalingFactor); + try { + // first cleanup previous temp scaledimage file if necesary + if (scaledImage != null) { + scaledImage.cleanup(); + } + // now create temp file and execute convert + scaledImage = sourceImage.scale(aScalingFactor); + } + catch (Exception e) { + throw new MediaExc(e.toString()); + } + logger.debug(" scaledImage:"); + scaledImage.debugOutput(); + } + + public int getWidth() { + return sourceImage.width; + } + + public int getHeight() { + return sourceImage.height; + } + + public int getScaledWidth() { + return scaledImage.width; + } + + public int getScaledHeight() { + return scaledImage.height; + } + + public int getScaledFileSize() { + return scaledImage.fileSize; + } + + public void writeScaledData(OutputStream aStream, String anImageType) throws MediaExc, IOException { + // we can't asume that requested "anImageType" is the same as the + // scaled image type, so we have to convert + // if image is an animation and target type doesn't support + // animations, then just use first frame + String frame = ""; + scaledImage.debugOutput(); + + if (scaledImage.isAnimation && !anImageType.equals("GIF")) { + frame = "[0]"; + } + // ImageMagick "convert" into temp file + File temp = File.createTempFile("mirimage", ""); + String command = getImageMagickPath() + "convert " + + scaledImage.file.getAbsolutePath() + frame + " " + + anImageType + ":" + temp.getAbsolutePath(); + logger.debug("writeScaledData command:" + command); + ShellRoutines.simpleExec(command); + // copy temp file into stream + StreamCopier.copy(new FileInputStream(temp), aStream); + temp.delete(); + } + + public void writeScaledData(File aFile, String anImageType) throws MediaExc, IOException, FileNotFoundException { + OutputStream stream = new BufferedOutputStream(new FileOutputStream(aFile), 8192); + + try { + writeScaledData(stream, anImageType); + } + finally { + try { + stream.close(); + } + catch (Throwable t) { + } + } + } + + /** + * 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 \" " + + 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; + 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; + } + } +} \ No newline at end of file diff --git a/source/mir/media/image/ImageProcessor.java b/source/mir/media/image/ImageProcessor.java index 7ed0983c..2879d549 100755 --- a/source/mir/media/image/ImageProcessor.java +++ b/source/mir/media/image/ImageProcessor.java @@ -1,87 +1,85 @@ -/* - * Copyright (C) 2005 The Mir-coders group - * - * This file is part of Mir. - * - * Mir is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Mir is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mir; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with any library licensed under the Apache Software License. - * You must obey the GNU General Public License in all respects for all of the code used - * other than the above mentioned libraries. If you modify this file, you may extend this - * exception to your version of the file, but you are not obligated to do so. - * If you do not wish to do so, delete this exception statement from your version. - */ -package mir.media.image; - -import mir.media.MediaExc; - -import java.io.File; -import java.io.OutputStream; - -public interface ImageProcessor { - public void descaleImage(int aMaxSize) throws MediaExc; - - public void descaleImage(int aMaxSize, float aMinDescale) throws MediaExc; - - public void descaleImage(int aMaxSize, int aMinResize) throws MediaExc; - - public void descaleImage(int aMaxSize, float aMinDescale, int aMinResize) throws MediaExc; - - /** - * Resizes an image to fit inside aMaxWidth and aMaxHeight, provided - * this requires at least aMinResize pixels will be removed from either the width or - * the height - */ - public void descaleImage(int aMaxWidth, int aMaxHeight, float aMinDescale, int aMinResize) throws MediaExc; - - public void scaleImage(float aScalingFactor) throws MediaExc; - - public int getWidth(); - public int getHeight(); - public int getSourceFileSize(); - public int getScaledFileSize(); - public int getScaledWidth(); - public int getScaledHeight(); - public void writeScaledData(OutputStream aStream, String anImageType) - throws MediaExc; - public byte[] getScaledData(String anImageType) throws MediaExc; - public void writeScaledData(File aFile, String anImageType) throws MediaExc; - - /** - * call this when you're over using this object (removes temp files) - */ - public void cleanup(); -} - - - - - - - - - - - - - - - - - - - - +/* + * Copyright (C) 2005 The Mir-coders group + * + * This file is part of Mir. + * + * Mir is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Mir is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mir; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, The Mir-coders gives permission to link + * the code of this program with any library licensed under the Apache Software License. + * You must obey the GNU General Public License in all respects for all of the code used + * other than the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. + * If you do not wish to do so, delete this exception statement from your version. + */ +package mir.media.image; + +import mir.media.MediaExc; + +import java.io.File; +import java.io.OutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +public interface ImageProcessor { + void descaleImage(int aMaxSize) throws MediaExc; + + void descaleImage(int aMaxSize, float aMinDescale) throws MediaExc; + + void descaleImage(int aMaxSize, int aMinResize) throws MediaExc; + + void descaleImage(int aMaxSize, float aMinDescale, int aMinResize) throws MediaExc; + + /** + * Resizes an image to fit inside aMaxWidth and aMaxHeight, provided + * this requires at least aMinResize pixels will be removed from either the width or + * the height + */ + void descaleImage(int aMaxWidth, int aMaxHeight, float aMinDescale, int aMinResize) throws MediaExc; + + void scaleImage(float aScalingFactor) throws MediaExc; + + int getWidth(); + int getHeight(); + int getScaledFileSize(); + int getScaledWidth(); + int getScaledHeight(); + void writeScaledData(OutputStream aStream, String anImageType) throws MediaExc, IOException; + void writeScaledData(File aFile, String anImageType) throws MediaExc, IOException, FileNotFoundException; + + /** + * call this when you're over using this object (removes temp files) + */ + void cleanup(); +} + + + + + + + + + + + + + + + + + + + diff --git a/source/mircoders/media/MediaHandlerImagesExtern.java b/source/mircoders/media/MediaHandlerImagesExtern.java index bb00c94f..61f6017e 100755 --- a/source/mircoders/media/MediaHandlerImagesExtern.java +++ b/source/mircoders/media/MediaHandlerImagesExtern.java @@ -1,177 +1,187 @@ -/* - * Copyright (C) 2001, 2002 The Mir-coders group - * - * This file is part of Mir. - * - * Mir is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Mir is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mir; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with any library licensed under the Apache Software License, - * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library - * (or with modified versions of the above that use the same license as the above), - * and distribute linked combinations including the two. You must obey the - * GNU General Public License in all respects for all of the code used other than - * the above mentioned libraries. If you modify this file, you may extend this - * exception to your version of the file, but you are not obligated to do so. - * If you do not wish to do so, delete this exception statement from your version. - */ -package mircoders.media; - - -import mir.entity.Entity; -import mir.log.LoggerWrapper; -import mir.media.MediaExc; -import mir.media.MediaFailure; -import mir.media.image.ImageMagickImageProcessor; -import mir.media.image.ImageProcessor; -import mir.misc.StringUtil; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * Image handler that stores images outside of the database. - * - * @author Zapata - * @version 1.0 - */ - -public class MediaHandlerImagesExtern extends MediaHandlerGeneric { - private int maxIconSize; - private float minDescaleRatio; - private int minDescaleReduction; - - public MediaHandlerImagesExtern() { - - logger = new LoggerWrapper("Media.Images.Extern"); - - maxIconSize = configuration.getInt("Producer.Image.MaxIconSize"); - minDescaleRatio = configuration.getFloat("Producer.Image.MinDescalePercentage")/100; - minDescaleReduction = configuration.getInt("Producer.Image.MinDescaleReduction"); - } - - public void produce(Entity anImageEntity, Entity aMediaTypeEntity) throws MediaExc, MediaFailure { - String date = anImageEntity.getFieldValue("date"); - String datePath = StringUtil.webdbDate2path(date); - String ext = "." + aMediaTypeEntity.getFieldValue("name"); - String fileBasePath = datePath + anImageEntity.getId(); - String filePath = fileBasePath + ext; - String iconPath = getBaseIconStoragePath() + fileBasePath + ".jpg"; - String iconStoragePath = configuration.getString("Producer.StorageRoot") + iconPath; - String imageFilePath = getBaseStoragePath() + File.separator + filePath; - - File imageFile = new File(imageFilePath); - File iconFile = new File(iconStoragePath); - - if (!imageFile.exists()) { - throw new MediaExc("error in MediaHandlerImagesExtern.execute(): " + filePath + " does not exist!"); - } - else { - ImageProcessor processor; - try { - processor = new ImageMagickImageProcessor(imageFile); - } - catch (IOException e) { - throw new MediaFailure(e); - } - - processor.descaleImage(maxIconSize, minDescaleRatio, minDescaleReduction); - File dir = new File(iconFile.getParent()); - if (dir!=null && !dir.exists()){ - dir.mkdirs(); - } - processor.writeScaledData(iconFile, "JPEG"); - - anImageEntity.setFieldValue("img_height", - Integer.toString(processor.getHeight())); - anImageEntity.setFieldValue("img_width", - Integer.toString(processor.getWidth())); - - anImageEntity.setFieldValue("icon_height", - Integer.toString(processor.getScaledHeight())); - anImageEntity.setFieldValue("icon_width", - Integer.toString(processor.getScaledWidth())); - - processor.cleanup(); - anImageEntity.setFieldValue("icon_path", iconPath); - anImageEntity.setFieldValue("publish_path", filePath); - - anImageEntity.update(); - reportChange(iconStoragePath); - reportChange(imageFilePath); - } - } - - - /** {@inheritDoc} */ - public InputStream getThumbnail(Entity anImageEntity) throws MediaExc, MediaFailure { - try { - File file = new File(configuration.getString("Producer.StorageRoot") + anImageEntity.getFieldValue("icon_path")); - - if (!file.exists()) { - // hackish - file = new File(configuration.getHome(), "../img/photo_big.gif"); - } - - return new BufferedInputStream( - new FileInputStream(file),8192); - } - catch (Throwable t) { - return null; - } - } - - public String getIconMimeType(Entity anImageEntity, Entity aMediaType) { - return "image/jpeg"; - } - - public String getBaseStoragePath() - { - return configuration.getString("Producer.Image.Path"); - } - - public String getBaseIconStoragePath() - { - return configuration.getString("Producer.Image.IconPath"); - } - - public String getPublishHost() - { - return StringUtil.removeSlash(configuration.getString("Producer.Image.Host")); - } - - public String getTinyIconName() - { - return configuration.getString("Producer.Icon.TinyImage"); - } - - public String getBigIconName() - { - return configuration.getString("Producer.Icon.BigImage"); - } - - public String getIconAltName() - { - return "Image"; - } - - public String getDescr(Entity mediaType) - { - return "image/jpeg"; - } -} +/* + * Copyright (C) 2001, 2002 The Mir-coders group + * + * This file is part of Mir. + * + * Mir is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Mir is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mir; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, The Mir-coders gives permission to link + * the code of this program with any library licensed under the Apache Software License, + * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library + * (or with modified versions of the above that use the same license as the above), + * and distribute linked combinations including the two. You must obey the + * GNU General Public License in all respects for all of the code used other than + * the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. + * If you do not wish to do so, delete this exception statement from your version. + */ +package mircoders.media; + + +import mir.entity.Entity; +import mir.log.LoggerWrapper; +import mir.media.MediaExc; +import mir.media.MediaFailure; +import mir.media.image.ImageMagickImageProcessor; +import mir.media.image.ImageProcessor; +import mir.misc.StringUtil; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +/** + * Image handler that stores images outside of the database. + * + * @author Zapata + * @version 1.0 + */ + +public class MediaHandlerImagesExtern extends MediaHandlerGeneric { + private int maxIconSize; + private float minDescaleRatio; + private int minDescaleReduction; + + public MediaHandlerImagesExtern() { + + logger = new LoggerWrapper("Media.Images.Extern"); + + maxIconSize = configuration.getInt("Producer.Image.MaxIconSize"); + minDescaleRatio = configuration.getFloat("Producer.Image.MinDescalePercentage")/100; + minDescaleReduction = configuration.getInt("Producer.Image.MinDescaleReduction"); + } + + public void produce(Entity anImageEntity, Entity aMediaTypeEntity) throws MediaExc, MediaFailure { + String date = anImageEntity.getFieldValue("date"); + String datePath = StringUtil.webdbDate2path(date); + String ext = "." + aMediaTypeEntity.getFieldValue("name"); + String fileBasePath = datePath + anImageEntity.getId(); + String filePath = fileBasePath + ext; + String iconPath = getBaseIconStoragePath() + fileBasePath + ".jpg"; + String iconStoragePath = configuration.getString("Producer.StorageRoot") + iconPath; + String imageFilePath = getBaseStoragePath() + File.separator + filePath; + + File imageFile = new File(imageFilePath); + File iconFile = new File(iconStoragePath); + + if (!imageFile.exists()) { + throw new MediaExc("error in MediaHandlerImagesExtern.execute(): " + filePath + " does not exist!"); + } + else { + ImageProcessor processor; + try { + processor = new ImageMagickImageProcessor(imageFile); + } + catch (IOException e) { + throw new MediaFailure(e); + } + + processor.descaleImage(maxIconSize, minDescaleRatio, minDescaleReduction); + File dir = new File(iconFile.getParent()); + if (dir!=null && !dir.exists()){ + dir.mkdirs(); + } + try { + processor.writeScaledData(iconFile, "JPEG"); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + anImageEntity.setFieldValue("img_height", + Integer.toString(processor.getHeight())); + anImageEntity.setFieldValue("img_width", + Integer.toString(processor.getWidth())); + + anImageEntity.setFieldValue("icon_height", + Integer.toString(processor.getScaledHeight())); + anImageEntity.setFieldValue("icon_width", + Integer.toString(processor.getScaledWidth())); + + processor.cleanup(); + anImageEntity.setFieldValue("icon_path", iconPath); + anImageEntity.setFieldValue("publish_path", filePath); + + anImageEntity.update(); + reportChange(iconStoragePath); + reportChange(imageFilePath); + } + } + + + /** {@inheritDoc} */ + public InputStream getThumbnail(Entity anImageEntity) throws MediaExc, MediaFailure { + try { + File file = new File(configuration.getString("Producer.StorageRoot") + anImageEntity.getFieldValue("icon_path")); + + if (!file.exists()) { + // hackish + file = new File(configuration.getHome(), "../img/photo_big.gif"); + } + + return new BufferedInputStream( + new FileInputStream(file),8192); + } + catch (Throwable t) { + return null; + } + } + + public String getIconMimeType(Entity anImageEntity, Entity aMediaType) { + return "image/jpeg"; + } + + public String getBaseStoragePath() + { + return configuration.getString("Producer.Image.Path"); + } + + public String getBaseIconStoragePath() + { + return configuration.getString("Producer.Image.IconPath"); + } + + public String getPublishHost() + { + return StringUtil.removeSlash(configuration.getString("Producer.Image.Host")); + } + + public String getTinyIconName() + { + return configuration.getString("Producer.Icon.TinyImage"); + } + + public String getBigIconName() + { + return configuration.getString("Producer.Icon.BigImage"); + } + + public String getIconAltName() + { + return "Image"; + } + + public String getDescr(Entity mediaType) + { + return "image/jpeg"; + } +} diff --git a/source/mircoders/media/MediaHandlerImagesExternScaling.java b/source/mircoders/media/MediaHandlerImagesExternScaling.java index 5b48ec2e..1afa0194 100644 --- a/source/mircoders/media/MediaHandlerImagesExternScaling.java +++ b/source/mircoders/media/MediaHandlerImagesExternScaling.java @@ -1,220 +1,229 @@ -/* - * Copyright (C) 2001, 2002 The Mir-coders group - * - * This file is part of Mir. - * - * Mir is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Mir is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mir; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with any library licensed under the Apache Software License, - * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library - * (or with modified versions of the above that use the same license as the above), - * and distribute linked combinations including the two. You must obey the - * GNU General Public License in all respects for all of the code used other than - * the above mentioned libraries. If you modify this file, you may extend this - * exception to your version of the file, but you are not obligated to do so. - * If you do not wish to do so, delete this exception statement from your version. - */ -package mircoders.media; - - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -import mir.entity.Entity; -import mir.log.LoggerWrapper; -import mir.media.MediaExc; -import mir.media.MediaFailure; -import mir.media.image.ImageMagickImageProcessor; -import mir.media.image.ImageProcessor; -import mir.misc.StringUtil; -import mir.util.FileRoutines; - -/** - * Image handler that stores images outside of the database. - * - * @author Zapata - * @version 1.0 - */ - -public class MediaHandlerImagesExternScaling extends MediaHandlerGeneric -{ - private int maxSize; - private int maxIconSize; - private float minDescaleRatio; - private int minDescaleReduction; - public MediaHandlerImagesExternScaling() { - logger = new LoggerWrapper("Media.Images.Extern"); - maxSize = configuration.getInt("Producer.Image.MaxSize"); - maxIconSize = configuration.getInt("Producer.Image.MaxIconSize"); - minDescaleRatio = configuration.getFloat("Producer.Image.MinDescalePercentage")/100; - minDescaleReduction = configuration.getInt("Producer.Image.MinDescaleReduction"); - } - - - - public void produce(Entity anImageEntity, Entity mediaTypeEnt) throws MediaExc, MediaFailure { - try { - String date = anImageEntity.getFieldValue("date"); - String datePath = StringUtil.webdbDate2path(date); - String ext = "." + mediaTypeEnt.getFieldValue("name"); - String fileBasePath = datePath + anImageEntity.getId(); - String filePath = fileBasePath + ext; - - String imageFilePath = getBaseStoragePath() + File.separator + filePath; - File imageFile = new File(imageFilePath); - - if (!imageFile.exists()) { - throw new MediaExc("error in MediaHandlerImagesExtern.execute(): " - + filePath + " does not exist!"); - } else { - ImageProcessor processor = new ImageMagickImageProcessor(imageFile); - String iconPath = getBaseIconStoragePath() + fileBasePath + ".jpg"; - String iconStoragePath = doIconScaling(processor, iconPath); - anImageEntity.setFieldValue("icon_height", new Integer(processor.getScaledHeight()).toString()); - anImageEntity.setFieldValue("icon_width", new Integer(processor.getScaledWidth()).toString()); - anImageEntity.setFieldValue("icon_path", iconPath); - - String imageOriginalRelPath = doImageScaling(filePath, imageFile, processor); - anImageEntity.setFieldValue("original_file_path", imageOriginalRelPath); - anImageEntity.setFieldValue("img_height", Integer.toString(processor.getScaledHeight())); - anImageEntity.setFieldValue("img_width", Integer.toString(processor.getScaledWidth())); - - processor.cleanup(); - anImageEntity.setFieldValue("publish_path", filePath); - anImageEntity.update(); - reportChange(iconStoragePath); - reportChange(imageFilePath); - } - } - catch(Throwable t) { - logger.error("MediaHandlerImagesExtern.execute: " + t.getMessage(), t); - throw new MediaFailure(t.getMessage(), t); - } - } - - /** - * Scale an icon image and write it to the file system. - * @param processor - * @param iconPath - * @return - * @throws MediaExc - */ - private String doIconScaling(ImageProcessor processor, String iconPath) throws MediaExc { - String iconStoragePath = configuration.getString("Producer.StorageRoot") + iconPath; - File iconFile = new File(iconStoragePath); - processor.descaleImage(maxIconSize, minDescaleRatio, minDescaleReduction); - File dir = new File(iconFile.getParent()); - if (dir != null && !dir.exists()) { - dir.mkdirs(); - } - processor.writeScaledData(iconFile, "JPEG"); - return iconStoragePath; - } - - /** - * Make the resized file. - * @param filePath - * @param imageFile - * @param processor - * @return - * @throws MediaExc - * @throws IOException - */ - private String doImageScaling(String filePath, File imageFile, ImageProcessor processor) throws MediaExc, IOException { - // get a file path where the the original image should be saved if image resizing is turned on - String imagesOriginalDir = configuration.getString("Producer.ImagesOriginalDir.Path"); - String imagesOriginalDirRelPath = configuration.getString("Producer.ImagesOriginalDir.RelPath"); - String imageOriginalFilePath = imagesOriginalDir + filePath; - String imageOriginalRelPath = imagesOriginalDirRelPath + filePath; - File originalFile = new File(imageOriginalFilePath); - processor.descaleImage(maxSize, minDescaleRatio, minDescaleReduction); - File originalDir = new File(originalFile.getParent()); - if (originalDir != null && !originalDir.exists()) { - originalDir.mkdirs(); - } - if (!originalFile.exists()) { - FileRoutines.copy(imageFile, originalFile); - reportChange(originalFile.getAbsolutePath()); - } - // yoss: don't write the scaled data again if it's the same size as - // the file that's there right now. Image producer runs are 4 times - // faster this way. - if (processor.getScaledFileSize() != imageFile.length()) { - processor.writeScaledData(imageFile, "JPEG"); - } - return imageOriginalRelPath; - } - -/** {@inheritDoc} */ - public InputStream getThumbnail(Entity anImageEntity) throws MediaExc, MediaFailure { - try { - File file = new File(configuration.getString("Producer.StorageRoot") + anImageEntity.getFieldValue("icon_path")); - - if (!file.exists()) { - // hackish - file = new File(configuration.getHome(), "../img/photo_big.gif"); - } - - return new BufferedInputStream( - new FileInputStream(file),8192); - } - catch (Throwable t) { - return null; - } - } - - public String getIconMimeType(Entity anImageEntity, Entity aMediaType) { - return "image/jpeg"; - } - - public String getBaseStoragePath() - { - return configuration.getString("Producer.Image.Path"); - } - - public String getBaseIconStoragePath() - { - return configuration.getString("Producer.Image.IconPath"); - } - - public String getPublishHost() - { - return StringUtil.removeSlash(configuration.getString("Producer.Image.Host")); - } - - public String getTinyIconName() - { - return configuration.getString("Producer.Icon.TinyImage"); - } - - public String getBigIconName() - { - return configuration.getString("Producer.Icon.BigImage"); - } - - public String getIconAltName() - { - return "Image"; - } - - public String getDescr(Entity mediaType) - { - return "image/jpeg"; - } -} +/* + * Copyright (C) 2001, 2002 The Mir-coders group + * + * This file is part of Mir. + * + * Mir is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Mir is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mir; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, The Mir-coders gives permission to link + * the code of this program with any library licensed under the Apache Software License, + * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library + * (or with modified versions of the above that use the same license as the above), + * and distribute linked combinations including the two. You must obey the + * GNU General Public License in all respects for all of the code used other than + * the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. + * If you do not wish to do so, delete this exception statement from your version. + */ +package mircoders.media; + + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import mir.entity.Entity; +import mir.log.LoggerWrapper; +import mir.media.MediaExc; +import mir.media.MediaFailure; +import mir.media.image.ImageMagickImageProcessor; +import mir.media.image.ImageProcessor; +import mir.misc.StringUtil; +import mir.util.FileRoutines; + +/** + * Image handler that stores images outside of the database. + * + * @author Zapata + * @version 1.0 + */ + +public class MediaHandlerImagesExternScaling extends MediaHandlerGeneric +{ + private int maxSize; + private int maxIconSize; + private float minDescaleRatio; + private int minDescaleReduction; + public MediaHandlerImagesExternScaling() { + logger = new LoggerWrapper("Media.Images.Extern"); + maxSize = configuration.getInt("Producer.Image.MaxSize"); + maxIconSize = configuration.getInt("Producer.Image.MaxIconSize"); + minDescaleRatio = configuration.getFloat("Producer.Image.MinDescalePercentage")/100; + minDescaleReduction = configuration.getInt("Producer.Image.MinDescaleReduction"); + } + + + + public void produce(Entity anImageEntity, Entity mediaTypeEnt) throws MediaExc, MediaFailure { + try { + String date = anImageEntity.getFieldValue("date"); + String datePath = StringUtil.webdbDate2path(date); + String ext = "." + mediaTypeEnt.getFieldValue("name"); + String fileBasePath = datePath + anImageEntity.getId(); + String filePath = fileBasePath + ext; + + String imageFilePath = getBaseStoragePath() + File.separator + filePath; + File imageFile = new File(imageFilePath); + + if (!imageFile.exists()) { + throw new MediaExc("error in MediaHandlerImagesExtern.execute(): " + + filePath + " does not exist!"); + } else { + ImageProcessor processor = new ImageMagickImageProcessor(imageFile); + String iconPath = getBaseIconStoragePath() + fileBasePath + ".jpg"; + String iconStoragePath = doIconScaling(processor, iconPath); + anImageEntity.setFieldValue("icon_height", new Integer(processor.getScaledHeight()).toString()); + anImageEntity.setFieldValue("icon_width", new Integer(processor.getScaledWidth()).toString()); + anImageEntity.setFieldValue("icon_path", iconPath); + + String imageOriginalRelPath = doImageScaling(filePath, imageFile, processor); + anImageEntity.setFieldValue("original_file_path", imageOriginalRelPath); + anImageEntity.setFieldValue("img_height", Integer.toString(processor.getScaledHeight())); + anImageEntity.setFieldValue("img_width", Integer.toString(processor.getScaledWidth())); + + processor.cleanup(); + anImageEntity.setFieldValue("publish_path", filePath); + anImageEntity.update(); + reportChange(iconStoragePath); + reportChange(imageFilePath); + } + } + catch(Throwable t) { + logger.error("MediaHandlerImagesExtern.execute: " + t.getMessage(), t); + throw new MediaFailure(t.getMessage(), t); + } + } + + /** + * Scale an icon image and write it to the file system. + * @param processor + * @param iconPath + * @return + * @throws MediaExc + */ + private String doIconScaling(ImageProcessor processor, String iconPath) throws MediaExc { + String iconStoragePath = configuration.getString("Producer.StorageRoot") + iconPath; + File iconFile = new File(iconStoragePath); + processor.descaleImage(maxIconSize, minDescaleRatio, minDescaleReduction); + File dir = new File(iconFile.getParent()); + if (dir != null && !dir.exists()) { + dir.mkdirs(); + } + try { + processor.writeScaledData(iconFile, "JPEG"); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return iconStoragePath; + } + + /** + * Make the resized file. + * @param filePath + * @param imageFile + * @param processor + * @return + * @throws MediaExc + * @throws IOException + */ + private String doImageScaling(String filePath, File imageFile, ImageProcessor processor) throws MediaExc, IOException { + // get a file path where the the original image should be saved if image resizing is turned on + String imagesOriginalDir = configuration.getString("Producer.ImagesOriginalDir.Path"); + String imagesOriginalDirRelPath = configuration.getString("Producer.ImagesOriginalDir.RelPath"); + String imageOriginalFilePath = imagesOriginalDir + filePath; + String imageOriginalRelPath = imagesOriginalDirRelPath + filePath; + File originalFile = new File(imageOriginalFilePath); + processor.descaleImage(maxSize, minDescaleRatio, minDescaleReduction); + File originalDir = new File(originalFile.getParent()); + if (originalDir != null && !originalDir.exists()) { + originalDir.mkdirs(); + } + if (!originalFile.exists()) { + FileRoutines.copy(imageFile, originalFile); + reportChange(originalFile.getAbsolutePath()); + } + // yoss: don't write the scaled data again if it's the same size as + // the file that's there right now. Image producer runs are 4 times + // faster this way. + if (processor.getScaledFileSize() != imageFile.length()) { + processor.writeScaledData(imageFile, "JPEG"); + } + return imageOriginalRelPath; + } + +/** {@inheritDoc} */ + public InputStream getThumbnail(Entity anImageEntity) throws MediaExc, MediaFailure { + try { + File file = new File(configuration.getString("Producer.StorageRoot") + anImageEntity.getFieldValue("icon_path")); + + if (!file.exists()) { + // hackish + file = new File(configuration.getHome(), "../img/photo_big.gif"); + } + + return new BufferedInputStream( + new FileInputStream(file),8192); + } + catch (Throwable t) { + return null; + } + } + + public String getIconMimeType(Entity anImageEntity, Entity aMediaType) { + return "image/jpeg"; + } + + public String getBaseStoragePath() + { + return configuration.getString("Producer.Image.Path"); + } + + public String getBaseIconStoragePath() + { + return configuration.getString("Producer.Image.IconPath"); + } + + public String getPublishHost() + { + return StringUtil.removeSlash(configuration.getString("Producer.Image.Host")); + } + + public String getTinyIconName() + { + return configuration.getString("Producer.Icon.TinyImage"); + } + + public String getBigIconName() + { + return configuration.getString("Producer.Icon.BigImage"); + } + + public String getIconAltName() + { + return "Image"; + } + + public String getDescr(Entity mediaType) + { + return "image/jpeg"; + } +} -- 2.11.0