I simply want to enable the user of my web site to change the orientation of a submitted photo from horizontal to vertical. Here's my code:
public static final void rotatePhoto(String jpgFilename){
BufferedImage originalImage = null, newImage=null;
try{
File file = new File(jpgFilename);
originalImage = ImageIO.read(file);
System.out.println("Photo.rotatePhoto(" +jpgFilename +") originalImage.getWidth(null)=" +originalImage.getWidth(null) +" originalImage.getHeight(null)=" +originalImage.getHeight(null) );
java.awt.image.AffineTransformOp opRotated = new java.awt.image.AffineTransformOp( java.awt.geom.AffineTransform.getQuadrantRotateInstance(1), null );
newImage = opRotated.createCompatibleDestImage(originalImage, originalImage.getColorModel());
opRotated.filter(originalImage, newImage);
}catch (IOException e){
}
/// Write result to file::::::::::::::::::::::::::::::::::::::::::::::::::::
try{
File outputfile = new File(testFilename);
ImageIO.write(newImage, "jpg", outputfile);
}catch(IOException ioE){
}
}
Problem is I get this error even though the System.out.println shows the width and height to be 640x480
java.awt.image.RasterFormatException: Transformed width (0) is less than or equal to 0.
java.awt.image.AffineTransformOp.createCompatibleDestImage(AffineTransformOp.java:447)
base.Photo.rotatePhoto(Photo.java:135)
base.ProcessContent.handleInput(ProcessContent.java:245)
servlets.ProcessServlet.doPost(ProcessServlet.java:74)
servlets.ProcessServlet.doGet(ProcessServlet.java:33)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
Any ideas or workarounds?
Try creating a new AffineTransform
from scratch and using it in your AffineTransformOp
constructor:
AffineTransform tx = new AffineTransform();
tx.rotate(Math.PI / 2, originalImage.getWidth() / 2, originalImage.getHeight() / 2);
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
newImage = op.filter(originalImage, newImage);
You also have to make sure newImage
contains the data returned by the filter()
method.
Oddly enough, this will only work when you set the formatName
in ImageIO.write()
to "png". I tried using jpg
and the result was a black picture.
By using: AffineTransform.getQuadrantRotateInstance(1);
Your AffineTransform is rotating by a positive number of quadrants by axis. That will mess up the Transform Operation since it depends on the x and y, whenever it creates the compatible image.
int w = r.x + r.width;
int h = r.y + r.height;
if (w <= 0) {
throw new RasterFormatException("Transformed width ("+w+
") is less than or equal to 0.");
}
I would recommend doing it yourself:
public final void rotatePhoto(String jpgFilename) throws IOException {
File file = new File(jpgFilename);
BufferedImage originalImage = ImageIO.read(file);
// You could use Math.PI / 2, depends on your input.
AffineTransform affineTransform = new AffineTransform();
affineTransform.rotate(Math.toRadians(90), originalImage.getWidth() / 2, originalImage.getHeight() / 2);
// Now lets make that transform an operation, and we use it.
AffineTransformOp opRotated = new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_BILINEAR);
BufferedImage newImage = opRotated.filter(originalImage, null);
// Save the image.
File outputfile = new File("rotated.jpg");
ImageIO.write(newImage, "jpg", outputfile);
}
UPDATE: Btw, it has been answered before on How do I write a servlet which rotates images?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With