I was using the image task to create thumbnails and couldn't figure out how to keep proportions of an image but keep it within a fixed size. My solution was to change the keepproportions attribute to be a little cleverer. The keepproportions attribute is no more and has been replaced by the proportions attribute, which has been added with the following features: proportions="ignore" - treat the dimensions independently (==keepproportions="false" and is default) proportions="width" - keep proportions based on the width (==keepproportions="true") proportions="height" - keep proportions based on the height proportions="fit" - keep proportions and fit in the supplied dimensions proportions="cover" - keep proportions and cover the supplied dimensions Submitted by: Rob Oxspring (roxspring at imapmail dot org) git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@275127 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -262,6 +262,9 @@ Other changes: | |||||
| * Added <image> task (requires JAI). | * Added <image> task (requires JAI). | ||||
| * <image> task has now proportions attribute in the <scale/> nested element | |||||
| instead of keepproportions (bringing in more functionality) | |||||
| * New condition <isreference> | * New condition <isreference> | ||||
| * <ftp> now has a preservelastmodified attribute to preserve the | * <ftp> now has a preservelastmodified attribute to preserve the | ||||
| @@ -138,11 +138,15 @@ ImageOperation can handle nested Rotate, Draw, Rectangle, Text and Scale objects | |||||
| <td valign="top"><b>Description</b></td> | <td valign="top"><b>Description</b></td> | ||||
| <td align="center" valign="top"><b>Required</b></td> | <td align="center" valign="top"><b>Required</b></td> | ||||
| </tr> | </tr> | ||||
| <tr> | |||||
| <td valign="top"> keepproportions </td> | |||||
| <td valign="top"> Boolean value. Sets whether the proportion heigth/width should be kept. </td> | |||||
| <td align="center"> no (defaults to <i>false</i>) </td> | |||||
| </tr> | |||||
| <td valign="top"> proportions </td> | |||||
| <td valign="top"> Sets which dimension to control proportions from. Valid values are:<ul> | |||||
| <li>"ignore" - treat the dimensions independently.</li> | |||||
| <li>"height" - keep proportions based on the width.</li> | |||||
| <li>"width" - keep proportions based on the height.</li> | |||||
| <li>"cover" - keep proportions and fit in the supplied dimensions.</li> | |||||
| <li>"fit" - keep proportions and cover the supplied dimensions.</li> | |||||
| </ul></td> | |||||
| + <td align="center"> no (defaults to <i>ignore</i>) </td> | |||||
| <tr> | <tr> | ||||
| <td valign="top"> width </td> | <td valign="top"> width </td> | ||||
| <td valign="top"> Sets the width of the image, either as an integer or a %. </td> | <td valign="top"> Sets the width of the image, either as an integer or a %. </td> | ||||
| @@ -18,35 +18,35 @@ | |||||
| <!-- this should produce a single file in the dest dir --> | <!-- this should produce a single file in the dest dir --> | ||||
| <target name="testSimpleScale" depends="init"> | <target name="testSimpleScale" depends="init"> | ||||
| <image includes="*.jpg" srcdir="${src.dir}" destdir="${dest.dir}" overwrite="no" failonerror="no"> | <image includes="*.jpg" srcdir="${src.dir}" destdir="${dest.dir}" overwrite="no" failonerror="no"> | ||||
| <scale width="300" keepproportions="true"/> | |||||
| <scale width="300" proportions="width"/> | |||||
| </image> | </image> | ||||
| </target> | </target> | ||||
| <!-- this should put some text in the log --> | <!-- this should put some text in the log --> | ||||
| <target name="testEchoToLog" depends="init"> | <target name="testEchoToLog" depends="init"> | ||||
| <image includes="*.jpg" srcdir="${src.dir}" destdir="${dest.dir}" overwrite="no" failonerror="no"> | <image includes="*.jpg" srcdir="${src.dir}" destdir="${dest.dir}" overwrite="no" failonerror="no"> | ||||
| <scale width="300" keepproportions="true"/> | |||||
| <scale width="300" proportions="width"/> | |||||
| </image> | </image> | ||||
| </target> | </target> | ||||
| <!-- this should produce a single file in the dest dir --> | <!-- this should produce a single file in the dest dir --> | ||||
| <target name="testFailOnError" depends="init"> | <target name="testFailOnError" depends="init"> | ||||
| <image includes="*.jpg" srcdir="${src.dir}" destdir="${dest.dir}" overwrite="no" failonerror="yes"> | <image includes="*.jpg" srcdir="${src.dir}" destdir="${dest.dir}" overwrite="no" failonerror="yes"> | ||||
| <scale width="300" keepproportions="true"/> | |||||
| <scale width="300" proportions="width"/> | |||||
| </image> | </image> | ||||
| </target> | </target> | ||||
| <!-- this should produce a single file in the dest dir, overwriting any existing file --> | <!-- this should produce a single file in the dest dir, overwriting any existing file --> | ||||
| <target name="testOverwriteTrue" depends="init"> | <target name="testOverwriteTrue" depends="init"> | ||||
| <image includes="*.jpg" srcdir="${src.dir}" destdir="${dest.dir}" overwrite="true" failonerror="no"> | <image includes="*.jpg" srcdir="${src.dir}" destdir="${dest.dir}" overwrite="true" failonerror="no"> | ||||
| <scale width="300" keepproportions="true"/> | |||||
| <scale width="300" proportions="width"/> | |||||
| </image> | </image> | ||||
| </target> | </target> | ||||
| <!-- this should not overwrite the existing file --> | <!-- this should not overwrite the existing file --> | ||||
| <target name="testOverwriteFalse" depends="init"> | <target name="testOverwriteFalse" depends="init"> | ||||
| <image includes="*.jpg" srcdir="${src.dir}" destdir="${dest.dir}" overwrite="false" failonerror="no"> | <image includes="*.jpg" srcdir="${src.dir}" destdir="${dest.dir}" overwrite="false" failonerror="no"> | ||||
| <scale width="300" keepproportions="true"/> | |||||
| <scale width="300" proportions="width"/> | |||||
| </image> | </image> | ||||
| </target> | </target> | ||||
| @@ -53,26 +53,42 @@ | |||||
| */ | */ | ||||
| package org.apache.tools.ant.types.optional.image; | package org.apache.tools.ant.types.optional.image; | ||||
| import org.apache.tools.ant.types.EnumeratedAttribute; | |||||
| import javax.media.jai.JAI; | import javax.media.jai.JAI; | ||||
| import javax.media.jai.PlanarImage; | import javax.media.jai.PlanarImage; | ||||
| import javax.media.jai.InterpolationBilinear; | |||||
| import java.awt.RenderingHints; | |||||
| import java.awt.image.BufferedImage; | import java.awt.image.BufferedImage; | ||||
| import java.awt.image.renderable.ParameterBlock; | import java.awt.image.renderable.ParameterBlock; | ||||
| /** | /** | ||||
| * | * | ||||
| * @author <a href="mailto:kzgrey@ntplx.net">Kevin Z Grey</a> | * @author <a href="mailto:kzgrey@ntplx.net">Kevin Z Grey</a> | ||||
| * @author <a href="mailto:roxspring@imapmail.org">Rob Oxspring</a> | |||||
| * @see org.apache.tools.ant.taskdefs.optional.image.Image | * @see org.apache.tools.ant.taskdefs.optional.image.Image | ||||
| */ | */ | ||||
| public class Scale extends TransformOperation implements DrawOperation { | public class Scale extends TransformOperation implements DrawOperation { | ||||
| private String width_str = "100%"; | private String width_str = "100%"; | ||||
| private String height_str = "100%"; | private String height_str = "100%"; | ||||
| private boolean x_percent = true; | private boolean x_percent = true; | ||||
| private boolean y_percent = true; | private boolean y_percent = true; | ||||
| private boolean keep_proportions = false; | |||||
| private String proportions = "ignore"; | |||||
| public static class ProportionsAttribute extends EnumeratedAttribute { | |||||
| public String[] getValues() { | |||||
| return new String[] {"ignore", "width", "height", "cover", "fit"}; | |||||
| } | |||||
| } | |||||
| public void setKeepproportions(boolean props) { | |||||
| keep_proportions = props; | |||||
| /** | |||||
| * Sets the behaviour regarding the image proportions. | |||||
| */ | |||||
| public void setProportions(ProportionsAttribute pa){ | |||||
| proportions = pa.getValue(); | |||||
| } | } | ||||
| /** | /** | ||||
| * Sets the width of the image, either as an integer or a %. Defaults to 100%. | * Sets the width of the image, either as an integer or a %. Defaults to 100%. | ||||
| */ | */ | ||||
| @@ -117,19 +133,32 @@ public class Scale extends TransformOperation implements DrawOperation { | |||||
| pb.addSource(image); | pb.addSource(image); | ||||
| float x_fl = getWidth(); | float x_fl = getWidth(); | ||||
| float y_fl = getHeight(); | float y_fl = getHeight(); | ||||
| if (!x_percent) { | if (!x_percent) { | ||||
| x_fl = (x_fl / image.getWidth()); | x_fl = (x_fl / image.getWidth()); | ||||
| } | } | ||||
| if (!y_percent) { | if (!y_percent) { | ||||
| y_fl = (y_fl / image.getHeight()); | y_fl = (y_fl / image.getHeight()); | ||||
| } | } | ||||
| if (keep_proportions) { | |||||
| if("width".equals(proportions)){ | |||||
| y_fl = x_fl; | y_fl = x_fl; | ||||
| } | } | ||||
| else if("height".equals(proportions)){ | |||||
| x_fl = y_fl; | |||||
| } | |||||
| else if("fit".equals(proportions)){ | |||||
| x_fl = y_fl = Math.min(x_fl,y_fl); | |||||
| } | |||||
| else if("cover".equals(proportions)){ | |||||
| x_fl = y_fl = Math.max(x_fl,y_fl); | |||||
| } | |||||
| pb.add(new Float(x_fl)); | pb.add(new Float(x_fl)); | ||||
| pb.add(new Float(y_fl)); | pb.add(new Float(y_fl)); | ||||
| log("\tScaling to " + x_fl + "% x " + y_fl + "%"); | |||||
| log("\tScaling to " + (x_fl*100) + "% x " + (y_fl*100)+ "%"); | |||||
| return JAI.create("scale", pb); | return JAI.create("scale", pb); | ||||
| } | } | ||||