在图像旋转后使用DrawImage()显示整个图像

时间:2014-04-18 16:16:28

标签: java image image-processing rotation java-2d

我正在使用AffineTransform旋转和缩放图像。当我使用Graphics2D.drawImage()显示图像时,整个图像都不会显示,因此我调用AffineTransform.translate方法。
这是我目前编写的代码:

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(); 
}

翻译方法有时会显示整个图像,有时不依赖于图像大小和旋转角度。无论如何都要确保旋转后显示整个图像。

我看了之前提出的问题: Java2D Image Rotation Issue 但是那里发布的解决方案给了我同样的问题。

2 个答案:

答案 0 :(得分:1)

我终于想出了一种方法来做到90度,它不适用于其他学位。

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();
   }

}

答案 1 :(得分:0)

  

有时显示整个图像,有时不依赖于图像大小和旋转角度

您需要重新计算旋转图像的大小。以下是如何执行此操作的示例:

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);
                }
            }
        });
    }
}

不确定缩放将如何影响这一点。也许你可以将宽度/高度乘以比例因子?