blob: f2b45edc43a0bd0ca3dafb0ad9e6605663d9976c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.types.optional.imageio;
import org.apache.tools.ant.types.EnumeratedAttribute;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
/**
*
* @see org.apache.tools.ant.taskdefs.optional.image.ImageIOTask
*/
public class Scale extends TransformOperation implements DrawOperation {
private static final int HUNDRED = 100;
private String widthStr = "100%";
private String heightStr = "100%";
private boolean xPercent = true;
private boolean yPercent = true;
private String proportions = "ignore";
/** Enumerated class for proportions attribute. */
public static class ProportionsAttribute extends EnumeratedAttribute {
/** {@inheritDoc}. */
@Override
public String[] getValues() {
return new String[] { "ignore", "width", "height", "cover", "fit" };
}
}
/**
* Sets the behaviour regarding the image proportions.
* @param pa the enumerated value.
*/
public void setProportions(ProportionsAttribute pa) {
proportions = pa.getValue();
}
/**
* Sets the width of the image, either as an integer or a %.
* Defaults to 100%.
* @param width the value to use.
*/
public void setWidth(String width) {
widthStr = width;
}
/**
* Sets the height of the image, either as an integer or a %. Defaults to 100%.
* @param height the value to use.
*/
public void setHeight(String height) {
heightStr = height;
}
/**
* Get the width.
* @return the value converted from the width string.
*/
public float getWidth() {
int percIndex = widthStr.indexOf('%');
if (percIndex > 0) {
xPercent = true;
float width = Float.parseFloat(widthStr.substring(0, percIndex));
return width / HUNDRED;
}
xPercent = false;
return Float.parseFloat(widthStr);
}
/**
* Get the height.
* @return the value converted from the height string.
*/
public float getHeight() {
int percIndex = heightStr.indexOf('%');
if (percIndex > 0) {
yPercent = true;
return Float.parseFloat(heightStr.substring(0, percIndex)) / HUNDRED;
}
yPercent = false;
return Float.parseFloat(heightStr);
}
/**
* Scale an image.
* @param image the image to scale.
* @return the scaled image.
*/
public BufferedImage performScale(BufferedImage image) {
float xFl = getWidth();
float yFl = getHeight();
if (!xPercent) {
xFl /= image.getWidth();
}
if (!yPercent) {
yFl /= image.getHeight();
}
if ("width".equals(proportions)) {
yFl = xFl;
} else if ("height".equals(proportions)) {
xFl = yFl;
} else if ("fit".equals(proportions)) {
yFl = Math.min(xFl, yFl);
xFl = yFl;
} else if ("cover".equals(proportions)) {
yFl = Math.max(xFl, yFl);
xFl = yFl;
}
log("\tScaling to " + (xFl * HUNDRED) + "% x "
+ (yFl * HUNDRED) + "%");
AffineTransform tx = AffineTransform.getScaleInstance(xFl, yFl);
BufferedImage scaleImage = new BufferedImage((int) (xFl * image.getWidth()),
(int) (yFl * image.getHeight()), image.getType());
AffineTransformOp scaleOp = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
scaleOp.filter(image, scaleImage);
return scaleImage;
}
/** {@inheritDoc}. */
@Override
public BufferedImage executeTransformOperation(BufferedImage image) {
for (ImageOperation instr : instructions) {
if (instr instanceof DrawOperation) {
return performScale(image);
}
if (instr instanceof TransformOperation) {
image = ((TransformOperation) instr).executeTransformOperation(image);
}
}
return performScale(image);
}
/** {@inheritDoc}. */
@Override
public BufferedImage executeDrawOperation() {
for (ImageOperation instr : instructions) {
if (instr instanceof DrawOperation) {
BufferedImage image = null;
// If this TransformOperation has DrawOperation children
// then Rotate the first child and return.
performScale(image);
return image;
}
}
return null;
}
}