Update of /var/cvs/applications/resources/src/org/mmbase/util/images In directory james.mmbase.org:/tmp/cvs-serv5180/applications/resources/src/org/mmbase/util/images
Modified Files: ImageMagickImageConverter.java ImageConverter.java AbstractImageConverter.java Log Message: MMB-1678 Animated gifs are corrupted easily when scaled with ImageMagick See also: http://cvs.mmbase.org/viewcvs/applications/resources/src/org/mmbase/util/images See also: http://www.mmbase.org/jira/browse/MMB-1678 Index: ImageMagickImageConverter.java =================================================================== RCS file: /var/cvs/applications/resources/src/org/mmbase/util/images/ImageMagickImageConverter.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -b -r1.8 -r1.9 --- ImageMagickImageConverter.java 24 Jul 2007 16:27:58 -0000 1.8 +++ ImageMagickImageConverter.java 14 Jul 2008 12:30:07 -0000 1.9 @@ -9,16 +9,16 @@ */ package org.mmbase.util.images; -import java.util.*; -import java.util.regex.*; import java.io.*; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.mmbase.util.Encode; import org.mmbase.util.externalprocess.CommandLauncher; import org.mmbase.util.externalprocess.ProcessException; -import org.mmbase.util.Encode; - -import org.mmbase.util.logging.Logging; import org.mmbase.util.logging.Logger; +import org.mmbase.util.logging.Logging; /** * Converts images using ImageMagick. @@ -27,7 +27,7 @@ * @author Michiel Meeuwissen * @author Nico Klasens * @author Jaco de Groot - * @version $Id: ImageMagickImageConverter.java,v 1.8 2007/07/24 16:27:58 michiel Exp $ + * @version $Id: ImageMagickImageConverter.java,v 1.9 2008/07/14 12:30:07 nklasens Exp $ */ public class ImageMagickImageConverter extends AbstractImageConverter implements ImageConverter { private static final Logger log = Logging.getLoggerInstance(ImageMagickImageConverter.class); @@ -54,11 +54,12 @@ protected String host = "localhost"; protected int port = 1679; + protected List<String> excludeFormats = new ArrayList<String>(); /** - * This function initalises this class - * @param params a <code>Map</code> of <code>String</code>s containing informationn, this should contain the key's - * ImageConvert.ConverterRoot and ImageConvert.ConverterCommand specifing the converter root, and it can also contain + * This function initializes this class + * @param params a <code>Map</code> of <code>String</code>s containing information, this should contain the key's + * ImageConvert.ConverterRoot and ImageConvert.ConverterCommand specifying the converter root, and it can also contain * ImageConvert.DefaultImageFormat which can also be 'asis'. */ public void init(Map<String, String> params) { @@ -85,6 +86,15 @@ port = Integer.parseInt(tmp); } + tmp = params.get("ImageConvert.ExcludeFormats"); + if (tmp != null && ! tmp.equals("")) { + StringTokenizer tokenizer = new StringTokenizer(tmp, " ,"); + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + excludeFormats.add(token); + } + } + tmp = params.get("ImageConvert.Method"); if (tmp != null && ! tmp.equals("")) { if (tmp.equals("launcher")) { @@ -238,19 +248,23 @@ /** * This functions converts an image by the given parameters * @param input an array of <code>byte</code> which represents the original image + * @param sourceFormat original image format * @param commands a <code>List</code> of <code>String</code>s containing commands which are operations on the image which will be returned. - * ImageConvert.converterRoot and ImageConvert.converterCommand specifing the converter root.... + * ImageConvert.converterRoot and ImageConvert.converterCommand specifying the converter root.... * @return an array of <code>byte</code>s containing the new converted image. - * */ public byte[] convertImage(byte[] input, String sourceFormat, List<String> commands) { - byte[] pict = null; if (input == null) { log.error("Converting an empty image does not make sense."); - return pict; + return input; + } + if (excludeFormats.contains(sourceFormat)) { + log.debug("Conversion is excluded for image format: " + sourceFormat); + return input; } - if (commands != null) { + byte[] pict = null; + if (commands != null && !commands.isEmpty()) { ParseResult parsedCommands = getConvertCommands(commands); if (parsedCommands.format.equals("asis") && sourceFormat != null) { parsedCommands.format = sourceFormat; @@ -258,6 +272,12 @@ if (log.isDebugEnabled()) { log.debug("Converting image (" + input.length + " bytes) to '" + parsedCommands.format + "' ('" + parsedCommands.args + "') with cwd = " + parsedCommands.cwd); } + if ("gif".equals(parsedCommands.format)) { + if (isAnimated(input)) { + parsedCommands.args.add(0, "-coalesce"); + } + } + ByteArrayInputStream in = new ByteArrayInputStream(input); ByteArrayOutputStream out = new ByteArrayOutputStream(); convertImage(in, out, parsedCommands.args, parsedCommands.format, parsedCommands.cwd); @@ -270,11 +290,27 @@ } } } + else { + log.error("Converting with empty commands."); + log.error(Logging.stackTrace()); + } return pict; } + protected boolean isAnimated(byte[] rawimage) { + ImageInfo imageInfo = new ImageInfo(); + imageInfo.setDetermineImageNumber(true); + ByteArrayInputStream inp = new ByteArrayInputStream(rawimage); + + imageInfo.setInput(inp); + imageInfo.check(); + return (imageInfo.getNumberOfImages() > 1); + } + /** * Translates MMBase color format (without #) to an convert color format (with or without); + * @param c color to convert + * @return converted color */ protected String color(String c) { if (c.charAt(0) == 'X') { @@ -492,6 +528,9 @@ } /** + * Is command prefixed with '-' or '+' + * @param s command + * @return <code>true</code> when prefixed * @since MMBase-1.7 */ private boolean isCommandPrefixed(String s) { @@ -532,11 +571,11 @@ /** * Does the actual conversion. * - * @param pict Byte array with the original picture + * @param originalStream Byte stream with the original picture + * @param imageStream output stream with converted image bytes * @param cmd List with convert parameters. * @param format The picture format to output to (jpg, gif etc.). - * @return The result of the conversion (a picture). - * + * @param cwd Directory for fonts */ private void convertImage(InputStream originalStream, OutputStream imageStream, List<String> cmd, String format, File cwd) { Index: ImageConverter.java =================================================================== RCS file: /var/cvs/applications/resources/src/org/mmbase/util/images/ImageConverter.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -b -r1.1 -r1.2 --- ImageConverter.java 25 Oct 2006 14:10:55 -0000 1.1 +++ ImageConverter.java 14 Jul 2008 12:30:08 -0000 1.2 @@ -9,23 +9,38 @@ */ package org.mmbase.util.images; +import java.util.List; +import java.util.Map; +import java.io.*; + /** * Interface for classes that can convert images. * * @author Rico Jansen * @author Michiel Meeuwissen */ - -import java.util.List; -import java.util.Map; -import java.io.*; - public interface ImageConverter { void init(Map<String, String> params); + /** + * This functions converts an image by the given parameters + * @param input an array of <code>byte</code> which represents the original image + * @param sourceFormat original image format + * @param commands a <code>List</code> of <code>String</code>s containing commands which are operations on the image which will be returned. + * @return an array of <code>byte</code>s containing the new converted image. + */ byte[] convertImage(byte[] input, String sourceFormat, List<String> commands); + /** + * This functions converts an image by the given parameters + * @param input stream of <code>byte</code> which represents the original image + * @param sourceFormat original image format + * @param out stream of <code>byte</code>s containing the new converted image. + * @param commands a <code>List</code> of <code>String</code>s containing commands which are operations on the image which will be returned. + * @return number of bytes of converted image. + * @throws IOException When an error occurs when converting the image + * * @since MMBase-1.9 */ int convertImage(InputStream input, String sourceFormat, OutputStream out, List<String> commands) throws IOException; Index: AbstractImageConverter.java =================================================================== RCS file: /var/cvs/applications/resources/src/org/mmbase/util/images/AbstractImageConverter.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -b -r1.3 -r1.4 --- AbstractImageConverter.java 8 Mar 2007 08:51:38 -0000 1.3 +++ AbstractImageConverter.java 14 Jul 2008 12:30:08 -0000 1.4 @@ -21,22 +21,22 @@ import java.util.List; import java.util.Map; -public class AbstractImageConverter implements ImageConverter { +public abstract class AbstractImageConverter implements ImageConverter { + /** + * @see org.mmbase.util.images.ImageConverter#init(java.util.Map) + */ public void init(Map<String, String> params) { } - public byte[] convertImage(byte[] input, String sourceFormat, List<String> commands) { - try { - InputStream in = new BytesInputStream(input); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - convertImage(in, sourceFormat, out, commands); - return out.toByteArray(); - } catch (IOException ioe) { - return null; - } - } - + /** + * @see org.mmbase.util.images.ImageConverter#convertImage(byte[], java.lang.String, java.util.List) + */ + public abstract byte[] convertImage(byte[] input, String sourceFormat, List<String> commands); + + /** + * @see org.mmbase.util.images.ImageConverter#convertImage(java.io.InputStream, java.lang.String, java.io.OutputStream, java.util.List) + */ public int convertImage(InputStream input, String sourceFormat, OutputStream out, List<String> commands) throws IOException { byte[] bytes; if (input instanceof BytesInputStream) { _______________________________________________ Cvs mailing list Cvs@lists.mmbase.org http://lists.mmbase.org/mailman/listinfo/cvs