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
[email protected]
http://lists.mmbase.org/mailman/listinfo/cvs