Rotate Bufferedimage Inside JPAnel

Rotate BufferedImage Inside JPanel

I solved my own issue. The problem lay in the code:

myPicture.getType()

Since there is a lot of variability in the types of images you could put in to the program, the results are going to be unpredictable when you start drawing into the new BufferedImage. I solved the problem by setting the type explicitly, which in my case required

BufferedImage.TYPE_INT_ARGB

so the full statement read:

BufferedImage newImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

Java, JPanel crop image while rotating

When you rotate an image, it changes size, you need to create a new image whose bounds encompass this new size, for example

public Image rotateBy(Image image, double degrees) {

// The size of the original image
int w = source.getWidth();
int h = source.getHeight();
// The angel of the rotation in radians
double rads = Math.toRadians(degrees);
// Some nice math which demonstrates I have no idea what I'm talking about
// Okay, this calculates the amount of space the image will need in
// order not be clipped when it's rotated
double sin = Math.abs(Math.sin(rads));
double cos = Math.abs(Math.cos(rads));
int newWidth = (int) Math.floor(w * cos + h * sin);
int newHeight = (int) Math.floor(h * cos + w * sin);

// A new image, into which the original can be painted
BufferedImage rotated = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = rotated.createGraphics();
// The transformation which will be used to actually rotate the image
// The translation, actually makes sure that the image is positioned onto
// the viewable area of the image
AffineTransform at = new AffineTransform();
at.translate((newWidth - w) / 2, (newHeight - h) / 2);

// And we rotate about the center of the image...
int x = w / 2;
int y = h / 2;
at.rotate(rads, x, y);
g2d.setTransform(at);
// And we paint the original image onto the new image
g2d.drawImage(image, 0, 0, null);
g2d.dispose();

return rotated;
}

Then you just need to call it...

picLabel.setIcon(new ImageIcon(rotateBy(scaledImage, 22.5)));

Because setIcon is a bound property, it should trigger a layout and paint pass automatically, if not, you can simply call revalidate and repaint to trigger them manually

Rotating BufferedImage instances

I would use Graphics2D.drawImage(image, affinetranform, imageobserver).

The code example below rotates and translates an image to the center of the component. This is a screenshot of the result:

screenshot

public static void main(String[] args) throws IOException {
JFrame frame = new JFrame("Test");

frame.add(new JComponent() {
BufferedImage image = ImageIO.read(
new URL("http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png"));

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);

// create the transform, note that the transformations happen
// in reversed order (so check them backwards)
AffineTransform at = new AffineTransform();

// 4. translate it to the center of the component
at.translate(getWidth() / 2, getHeight() / 2);

// 3. do the actual rotation
at.rotate(Math.PI / 4);

// 2. just a scale because this image is big
at.scale(0.5, 0.5);

// 1. translate the object so that you rotate it around the
// center (easier :))
at.translate(-image.getWidth() / 2, -image.getHeight() / 2);

// draw the image
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(image, at, null);

// continue drawing other stuff (non-transformed)
//...
}
});

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
}


Related Topics



Leave a reply



Submit