Domanda

I am rotating and scaling the image using AffineTransform. When I display the image using Graphics2D.drawImage() the whole image does not get displayed so I am calling the AffineTransform.translate method.
Here is the code I have currently written:

protected void paintComponent(Graphics g) { 
  super.paintComponent(g); 
  Graphics2D g2d =   (Graphics2D) g.create(); 
  Dimension dim = getPreferredSize();
  int x = (getWidth() - image.getWidth(null)) / 2; 
  int y = (getHeight() - image.getHeight(null)) / 2; 
  double angle = Math.toRadians(rotateAngle); 
  AffineTransform identity = new AffineTransform();
  identity.scale(scale, scale); 
  identity.translate(x,y); 
  AffineTransform at = new AffineTransform(); 
  setPreferredSize(new Dimension((int)(identity.getTranslateX()+(image.getWidth(null)*scale)),(int)(identity.getTranslateY()+(image.getHeight(null)*scale))));  
  at.setTransform(identity);
  at.rotate(angle); 
  g2d.transform(at); 
  g2d.drawImage(image, 0, 0, this); 
  g2d.dispose(); 
}

The translate method sometimes displays the whole image and sometimes does not depending on the image size and rotating angle. Is there anyway to make sure the whole image gets displayed after a rotate.

I had a look at this previous asked question: Java2D Image Rotation Issue but the solution posted there gave the same problem for me.

È stato utile?

Soluzione

I finally figured out a way to do this for 90 degrees, it will not work for other degrees.

void rotate90(){
  if(image!=null){
            int w = image.getWidth(null); //the Width of the original image
    int h = image.getHeight(null);//the Height of the original image            
    if(w>h){
            BufferedImage dimg = new BufferedImage(w, w,  BufferedImage.TYPE_3BYTE_BGR );
            Graphics2D g = dimg.createGraphics();
            g.translate(-(w-h), 0);
            g.rotate(Math.toRadians(90), w/2, w/2);
            g.drawImage(image, 0, 0,null);
            BufferedImage bimg = new BufferedImage(h, w,  BufferedImage.TYPE_3BYTE_BGR );       
            Graphics2D g2 = (Graphics2D)bimg.getGraphics();
            g2.drawImage(dimg,0,0,h,w,0,0,h,w,null);
            dimg.flush();
            dimg=null;
            image = createImage(bimg.getSource());
            bimg.flush();
            bimg= null;
    }
    else{
            BufferedImage dimg = new BufferedImage(h, h,  BufferedImage.TYPE_3BYTE_BGR );
            Graphics2D g = dimg.createGraphics();
            g.translate(-(w-h), 0);
            g.rotate(Math.toRadians(90), w/2, w/2);
            g.drawImage(image, 0, 0,null);
            BufferedImage bimg = new BufferedImage(h, w,  BufferedImage.TYPE_3BYTE_BGR );       
            Graphics2D g2 = (Graphics2D)bimg.getGraphics();
            g2.drawImage(dimg,0,0,h,w,0,0,h,w,null);
            dimg.flush();
            dimg=null;
            image = createImage(bimg.getSource());
            bimg.flush();
            bimg= null;
    }
  }
}


void rotateClockWise(){
 if(image!=null){
 rotate90();
 setPanelsize();
 revalidate();       
 repaint();
   }

}

Altri suggerimenti

sometimes displays the whole image and sometimes does not depending on the image size and rotating angle

You need to recalculate the size of the rotated image. Here is an example of how to do that:

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;

public class Rotation
{
    BufferedImage image;
    JLabel label;

    public Rotation(BufferedImage image)
    {
        this.image = image;
    }

    private BufferedImage getImage(double theta)
    {
        //  Determine the size of the rotated image

        double cos = Math.abs(Math.cos(theta));
        double sin = Math.abs(Math.sin(theta));
        double width  = image.getWidth();
        double height = image.getHeight();
        int w = (int)(width * cos + height * sin);
        int h = (int)(width * sin + height * cos);

        //  Rotate and paint the original image onto a BufferedImage

        BufferedImage out = new BufferedImage(w, h, image.getType());
        Graphics2D g2 = out.createGraphics();
        g2.setPaint(UIManager.getColor("Panel.background"));
        g2.fillRect(0,0,w,h);
        double x = w/2;
        double y = h/2;
        AffineTransform at = AffineTransform.getRotateInstance(theta, x, y);
        x = (w - width)/2;
        y = (h - height)/2;
        at.translate(x, y);
        g2.drawRenderedImage(image, at);
        g2.dispose();
        return out;
    }

    private JLabel getLabel()
    {
        ImageIcon icon = new ImageIcon(image);
        label = new JLabel(icon);
        label.setHorizontalAlignment(JLabel.CENTER);
        return label;
    }

    private JSlider getSlider()
    {
        final JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 360, 0);
        slider.addChangeListener(new ChangeListener()
        {
            public void stateChanged(ChangeEvent e)
            {
                int value = slider.getValue();
                BufferedImage bi = getImage(Math.toRadians(value));
                label.setIcon(new ImageIcon(bi));
            }
        });
        return slider;
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    String path = "mong.jpg";
                    ClassLoader cl = Rotation.class.getClassLoader();
                    BufferedImage bi = ImageIO.read(cl.getResourceAsStream(path));
                    Rotation r = new Rotation(bi);
                    JFrame f = new JFrame();
                    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    f.getContentPane().add(new JScrollPane(r.getLabel()));
                    f.getContentPane().add(r.getSlider(), "South");
                    f.pack();
                    f.setLocation(200,200);
                    f.setVisible(true);
                }
                catch(IOException e)
                {
                    System.out.println(e);
                }
            }
        });
    }
}

Not sure how the scaling will affect this. Maybe you can just multiply the width/height by the scaling factor?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top