mirror of
https://github.com/apache/nifi.git
synced 2025-02-09 11:35:05 +00:00
NIFI-10392 - This closes #6330. ResizeImage - add option to maintain aspect ratio
Signed-off-by: Joe Witt <joewitt@apache.org>
This commit is contained in:
parent
777238eb32
commit
71ba581fd8
@ -17,6 +17,7 @@
|
||||
|
||||
package org.apache.nifi.processors.image;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Transparency;
|
||||
@ -88,6 +89,15 @@ public class ResizeImage extends AbstractProcessor {
|
||||
.allowableValues(RESIZE_DEFAULT, RESIZE_FAST, RESIZE_SMOOTH, RESIZE_REPLICATE, RESIZE_AREA_AVERAGING)
|
||||
.defaultValue(RESIZE_DEFAULT.getValue())
|
||||
.build();
|
||||
static final PropertyDescriptor KEEP_RATIO = new PropertyDescriptor.Builder()
|
||||
.displayName("Maintain aspect ratio")
|
||||
.name("keep-ratio")
|
||||
.description("Specifies if the ratio of the input image should be maintained")
|
||||
.expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
|
||||
.allowableValues("true", "false")
|
||||
.defaultValue("false")
|
||||
.required(true)
|
||||
.build();
|
||||
|
||||
static final Relationship REL_SUCCESS = new Relationship.Builder()
|
||||
.name("success")
|
||||
@ -104,6 +114,7 @@ public class ResizeImage extends AbstractProcessor {
|
||||
properties.add(IMAGE_WIDTH);
|
||||
properties.add(IMAGE_HEIGHT);
|
||||
properties.add(SCALING_ALGORITHM);
|
||||
properties.add(KEEP_RATIO);
|
||||
return properties;
|
||||
}
|
||||
|
||||
@ -122,16 +133,6 @@ public class ResizeImage extends AbstractProcessor {
|
||||
return;
|
||||
}
|
||||
|
||||
final int width, height;
|
||||
try {
|
||||
width = context.getProperty(IMAGE_WIDTH).evaluateAttributeExpressions(flowFile).asInteger();
|
||||
height = context.getProperty(IMAGE_HEIGHT).evaluateAttributeExpressions(flowFile).asInteger();
|
||||
} catch (final NumberFormatException nfe) {
|
||||
getLogger().error("Failed to resize {} due to {}", new Object[] { flowFile, nfe });
|
||||
session.transfer(flowFile, REL_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
final String algorithm = context.getProperty(SCALING_ALGORITHM).getValue();
|
||||
final int hints;
|
||||
if (algorithm.equalsIgnoreCase(RESIZE_DEFAULT.getValue())) {
|
||||
@ -176,6 +177,25 @@ public class ResizeImage extends AbstractProcessor {
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean keepRatio = context.getProperty(KEEP_RATIO).evaluateAttributeExpressions(flowFile).asBoolean();
|
||||
|
||||
int width, height;
|
||||
try {
|
||||
width = context.getProperty(IMAGE_WIDTH).evaluateAttributeExpressions(flowFile).asInteger();
|
||||
height = context.getProperty(IMAGE_HEIGHT).evaluateAttributeExpressions(flowFile).asInteger();
|
||||
|
||||
if(keepRatio) {
|
||||
Dimension finalDimension = getScaledDimension(image.getWidth(), image.getHeight(), width, height);
|
||||
width = finalDimension.width;
|
||||
height = finalDimension.height;
|
||||
}
|
||||
|
||||
} catch (final NumberFormatException nfe) {
|
||||
getLogger().error("Failed to resize {} due to {}", new Object[] { flowFile, nfe });
|
||||
session.transfer(flowFile, REL_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
try (final OutputStream out = session.write(flowFile)) {
|
||||
final Image scaledImage = image.getScaledInstance(width, height, hints);
|
||||
final BufferedImage scaledBufferedImg;
|
||||
@ -207,4 +227,12 @@ public class ResizeImage extends AbstractProcessor {
|
||||
session.getProvenanceReporter().modifyContent(flowFile, stopWatch.getElapsed(TimeUnit.MILLISECONDS));
|
||||
session.transfer(flowFile, REL_SUCCESS);
|
||||
}
|
||||
|
||||
public Dimension getScaledDimension(int originalWidth, int originalHeight, int boundWidth, int boundHeight) {
|
||||
double widthRatio = ((double) boundWidth) / originalWidth;
|
||||
double heightRatio = ((double) boundHeight) / originalHeight;
|
||||
double ratio = Math.min(widthRatio, heightRatio);
|
||||
return new Dimension((int) (originalWidth * ratio), (int) (originalHeight * ratio));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -157,4 +157,48 @@ public class TestResizeImage {
|
||||
final File out = new File("target/mspaint-8x10resized.png");
|
||||
ImageIO.write(img, "PNG", out);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResizeBiggerPNGWithRatio() throws IOException {
|
||||
final TestRunner runner = TestRunners.newTestRunner(new ResizeImage());
|
||||
runner.setProperty(ResizeImage.IMAGE_HEIGHT, "64");
|
||||
runner.setProperty(ResizeImage.IMAGE_WIDTH, "64");
|
||||
runner.setProperty(ResizeImage.SCALING_ALGORITHM, ResizeImage.RESIZE_SMOOTH);
|
||||
runner.setProperty(ResizeImage.KEEP_RATIO, "true");
|
||||
|
||||
runner.enqueue(Paths.get("src/test/resources/mspaint-8x10.png"));
|
||||
runner.run();
|
||||
|
||||
runner.assertAllFlowFilesTransferred(ResizeImage.REL_SUCCESS, 1);
|
||||
final MockFlowFile mff = runner.getFlowFilesForRelationship(ResizeImage.REL_SUCCESS).get(0);
|
||||
final byte[] data = mff.toByteArray();
|
||||
|
||||
final BufferedImage img = ImageIO.read(new ByteArrayInputStream(data));
|
||||
assertEquals(42, img.getWidth());
|
||||
assertEquals(64, img.getHeight());
|
||||
final File out = new File("target/mspaint-8x10resized.png");
|
||||
ImageIO.write(img, "PNG", out);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResizeSmallerPNGWithRatio() throws IOException {
|
||||
final TestRunner runner = TestRunners.newTestRunner(new ResizeImage());
|
||||
runner.setProperty(ResizeImage.IMAGE_HEIGHT, "5");
|
||||
runner.setProperty(ResizeImage.IMAGE_WIDTH, "5");
|
||||
runner.setProperty(ResizeImage.SCALING_ALGORITHM, ResizeImage.RESIZE_SMOOTH);
|
||||
runner.setProperty(ResizeImage.KEEP_RATIO, "true");
|
||||
|
||||
runner.enqueue(Paths.get("src/test/resources/mspaint-8x10.png"));
|
||||
runner.run();
|
||||
|
||||
runner.assertAllFlowFilesTransferred(ResizeImage.REL_SUCCESS, 1);
|
||||
final MockFlowFile mff = runner.getFlowFilesForRelationship(ResizeImage.REL_SUCCESS).get(0);
|
||||
final byte[] data = mff.toByteArray();
|
||||
|
||||
final BufferedImage img = ImageIO.read(new ByteArrayInputStream(data));
|
||||
assertEquals(3, img.getWidth());
|
||||
assertEquals(5, img.getHeight());
|
||||
final File out = new File("target/mspaint-8x10resized.png");
|
||||
ImageIO.write(img, "PNG", out);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user