From: yossarian Date: Mon, 15 Jan 2007 23:35:32 +0000 (+0000) Subject: Adding class MediaHandlerImagesExternScaling to take care of scaling images (this... X-Git-Tag: LATEST_MERGED_1_1~4 X-Git-Url: http://erislabs.net/gitweb/?p=mir.git;a=commitdiff_plain;h=af4481b9ed706a180ff01b619cdb9630de6521f4 Adding class MediaHandlerImagesExternScaling to take care of scaling images (this class can replace MediaHandlerImagesExtern, which doesn't scale images, if the site admins want image scaling). --- diff --git a/source/mircoders/localizer/basic/MirBasicMediaLocalizer.java b/source/mircoders/localizer/basic/MirBasicMediaLocalizer.java index 0dce0b6f..bd37d03c 100755 --- a/source/mircoders/localizer/basic/MirBasicMediaLocalizer.java +++ b/source/mircoders/localizer/basic/MirBasicMediaLocalizer.java @@ -54,6 +54,7 @@ public class MirBasicMediaLocalizer implements MirMediaLocalizer { registerMediaHandler("Audio", new MediaHandlerAudio()); registerMediaHandler("Generic", new MediaHandlerGeneric()); registerMediaHandler("ImagesExtern", new MediaHandlerImagesExtern()); + registerMediaHandler("ImagesExternScaling", new MediaHandlerImagesExternScaling()); registerMediaHandler("ImagesJpeg", new MediaHandlerImagesJpeg()); registerMediaHandler("ImagesPng", new MediaHandlerImagesPng()); registerMediaHandler("Mp3", new MediaHandlerMp3()); diff --git a/source/mircoders/media/MediaHandlerImagesExternScaling.java b/source/mircoders/media/MediaHandlerImagesExternScaling.java new file mode 100644 index 00000000..5b48ec2e --- /dev/null +++ b/source/mircoders/media/MediaHandlerImagesExternScaling.java @@ -0,0 +1,220 @@ +/* + * 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"; + } +}