Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
217 views
in Technique[技术] by (71.8m points)

java - Rotating BufferedImage changes its colors

I'm trying to code a class to seam carve images in x and y direction. The x direction is working, and to reduce the y direction I thought about simply rotating the image 90° and run the same code over the already rescaled image (in x direction only) and after that, rotate it back to its initial state.

I found something with AffineTransform and tried it. It actually produced a rotated image, but messed up the colors and I don't know why.

This is all the code:

import java.awt.image.BufferedImage;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.io.File;
import java.io.IOException;
import javafx.scene.paint.Color;
import javax.imageio.ImageIO;


public class example {
/**
 * @param args the command line arguments
 */
public static void main(String[] args) throws IOException {
    // TODO code application logic here

    BufferedImage imgIn = ImageIO.read(new File("landscape.jpg"));
    BufferedImage imgIn2 = imgIn;

    AffineTransform tx = new AffineTransform();
    tx.rotate(Math.PI/2, imgIn2.getWidth() / 2, imgIn2.getHeight() / 2);//(radian,arbit_X,arbit_Y)

    AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
    BufferedImage last = op.filter(imgIn2, null);//(sourse,destination)
    ImageIO.write(last, "JPEG", new File("distortedColors.jpg"));
}

}

Just alter the filename in
BufferedImage imgIn = ImageIO.read(new File("landscape.jpg")); and try it.

When executed, you get 4 images: a heatmap, an image with seams in it and a rescaled image. The last image is a test to see if the rotation worked and it should show a rotated image but with distorted colors...

Help would be greatly appreciated!

EDIT:

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The problem is with the AffineTransformOp You need :

AffineTransformOp.TYPE_NEAREST_NEIGHBOR

instead of the BILINEAR you have now.

Second paragraph from documentation hints towards this.

This class uses an affine transform to perform a linear mapping from 2D coordinates in the source image or Raster to 2D coordinates in the destination image or Raster. The type of interpolation that is used is specified through a constructor, either by a RenderingHints object or by one of the integer interpolation types defined in this class. If a RenderingHints object is specified in the constructor, the interpolation hint and the rendering quality hint are used to set the interpolation type for this operation.

The color rendering hint and the dithering hint can be used when color conversion is required. Note that the following constraints have to be met: The source and destination must be different. For Raster objects, the number of bands in the source must be equal to the number of bands in the destination.

So this works

AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...