问题就是,当我旋转的度数不是180°的时候,如果创建画笔的区域不是正方形,而是长方形,那么这个区域在旋转的时候就会有问题了,那就是旋转区域并没有随着角度的变化而变化,还是保持原始的矩形,这就导致原本在没有翻转时能够显示的内容,翻转后显示不全了,请问这该怎么办?请看图例:
原始图
旋转90°以后的图
旋转90°以后的图片,这时候区域已经错了,因为旋转以后的宽高应该是160x116,现在还是116x160
同理,旋转270°以后的图片也有同样的问题。
而旋转180°的图片是没有问题的。
看不到图的请到我的相册去看,我在图片下面添加了说明:
http://hi.csdn.net/space-6471331-do-album-id-57640.html就是上述的问题,请问该如何处理,才能使旋转到90°、270°或者其他角度时,裁剪矩形能够正确的改变大小?以下是源代码,复制到工程里就可以运行:
MyPanel.java
图片地址:
http://hiphotos.baidu.com/%C2%ACllg/pic/item/460f81d0ddc168079950277d.jpg
package drawimage;
import java.awt.*;
import javax.swing.*;
public class MyPanel extends JPanel{    private double xuanzhuan = 0 ;
    private Image image ;
    private ImageIcon ii ;
    private double xflip = 1;
    private double yflip = 1;
    private int degree = 0;
    private Rectangle clipRect ;
    private Rectangle drawRect;
    public MyPanel(){
        ii = new ImageIcon(MyPanel.class.getResource("1.jpg"));
        image = ii.getImage();
    }    public void paintComponent(Graphics g){        int drawX = (getWidth() - image.getWidth(this)) / 2;
        int drawY = (getHeight() - image.getHeight(this)) / 2;
        g.drawImage(image,drawX,drawY,this);        Graphics2D g2d = (Graphics2D)(g.create(drawX + 70,drawY + 20,116,160));
        
        g2d.setColor(Color.DARK_GRAY);
        g2d.fillRect(0,0,116,160);
        g2d.rotate(xuanzhuan,116 / 2,160 / 2);
        g2d.scale(xflip,yflip);        g2d.drawImage(image,-70,-20,null);
        g.dispose();
    }    public Image getImage(){
        return image;
    }    private double getXuanzhuan(){
        return xuanzhuan;
    }    private void setXuanzhuan(double xuanzhuan){
        this.xuanzhuan = xuanzhuan;
    }    protected int getDegree(){
        return this.degree;
    }    public void setDegree(int degree){
        this.degree = degree;
        this.degree %= 360;
        this.setXuanzhuan(Math.toRadians(this.degree));
    }    public void joinDegree(int degree){
        this.degree += degree;
        if(this.degree < 0)
            this.degree +=360;
        this.degree %= 360;
        this.setXuanzhuan(Math.toRadians(this.degree));
    }    public void setXFlip(){
        xflip = -xflip;
    }    public void setYFlip(){
        yflip = -yflip;
    }
}DrawImage.javapackage drawimage;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.awt.*;
public class DrawImage implements ActionListener{    JFrame frame;
    MyPanel panel;
    JButton rotate;
    JButton xflip;
    JButton yflip;
    public DrawImage() {
        frame = new JFrame("绘图Demo");
        frame.setSize(400,500);
        frame.setAlwaysOnTop(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());        panel = new MyPanel();
        frame.getContentPane().add(panel,BorderLayout.CENTER);        JPanel buttonPane = new JPanel(new GridLayout(1,3));
        frame.getContentPane().add(buttonPane,BorderLayout.SOUTH);        rotate = new JButton("旋转90°");
        xflip = new JButton("水平翻转");
        yflip = new JButton("垂直翻转");
        xflip.addActionListener(this);
        yflip.addActionListener(this);
        rotate.addActionListener(this);
        buttonPane.add(rotate);
        buttonPane.add(xflip);
        buttonPane.add(yflip);        frame.setVisible(true);
    }    public static void main(String[] args){
        new DrawImage();
    }    public void actionPerformed(ActionEvent e) {
        Object o = e.getSource();
        if(o.equals(xflip)){
            panel.setXFlip();
        }else if(o.equals(yflip)){
            panel.setYFlip();
        }else if(o.equals(rotate)){
            panel.joinDegree(-90);
        }
        panel.repaint();
    }
}

解决方案 »

  1. 我没搞过 2D。猜测一下,
    g2d.fillRect(0,0,116,160); 会不会也得跟着变呢?
      

  2. 我更新了一下代码,我在上面的例子中,局部区域想要实现的旋转效果是这样的:
    可以看到,每次旋转的时候,图像的宽高都发生了变化。以下是更改以后的代码,旋转的角度我写成了90°,可以改为任意角度:MyPanel.java
    package drawimage;
    import java.awt.*;
    import javax.swing.*;
    import java.awt.image.BufferedImage;
    import java.awt.geom.AffineTransform;
    public class MyPanel extends JPanel{    private double xuanzhuan = 0 ;
        private Image image ;
        private ImageIcon ii ;
        private double xflip = 1;
        private double yflip = 1;
        private int degree = 0;
        public MyPanel(){
            ii = new ImageIcon(MyPanel.class.getResource("1.jpg"));
            image = ii.getImage();
        }    public void paintComponent(Graphics g){        g.setColor(super.getBackground());
            g.fillRect(0,0,getWidth(),getHeight());
            int drawX = (getWidth() - image.getWidth(this)) / 2;
            int drawY = (getHeight() - image.getHeight(this)) / 2;
            Graphics2D g2d = (Graphics2D)g;
            g2d.rotate(xuanzhuan,getWidth() / 2,getHeight() / 2);
            g.drawImage(image,drawX,drawY,this);
        }    public Image getImage(){
            return image;
        }    private double getXuanzhuan(){
            return xuanzhuan;
        }    private void setXuanzhuan(double xuanzhuan){
            this.xuanzhuan = xuanzhuan;
        }    protected int getDegree(){
            return this.degree;
        }    public void setDegree(int degree){
            this.degree = degree;
            this.degree %= 360;
            this.setXuanzhuan(Math.toRadians(this.degree));
        }    public void joinDegree(int degree){
            this.degree += degree;
            if(this.degree < 0)
                this.degree +=360;
            this.degree %= 360;
            this.setXuanzhuan(Math.toRadians(this.degree));
        }    public void setXFlip(){
            xflip = -xflip;
        }    public void setYFlip(){
            yflip = -yflip;
        }
    }DrawImage.javapackage drawimage;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.*;
    import java.awt.*;
    public class DrawImage implements ActionListener{    JFrame frame;
        MyPanel panel;
        JButton rotate;
        JButton xflip;
        JButton yflip;
        JToggleButton auto ;
        JToggleButton autoAll;
        
        AutoRote autoRote ;
        Thread autoRoteThread;    public DrawImage() {
            frame = new JFrame("绘图Demo");
            frame.setSize(400,500);
            frame.setAlwaysOnTop(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());        panel = new MyPanel();
            frame.getContentPane().add(panel,BorderLayout.CENTER);        JPanel buttonPane = new JPanel(new GridLayout(1,3));
            frame.getContentPane().add(buttonPane,BorderLayout.SOUTH);        rotate = new JButton("旋转90°");
            xflip = new JButton("水平翻转");
            yflip = new JButton("垂直翻转");
            auto = new JToggleButton("局部自动旋转");
            xflip.addActionListener(this);
            yflip.addActionListener(this);
            rotate.addActionListener(this);
            auto.addActionListener(this);
            buttonPane.add(rotate);
            buttonPane.add(auto);
            buttonPane.add(xflip);
            buttonPane.add(yflip);
            
            autoRote = new AutoRote();
                    frame.setVisible(true);
        }    public static void main(String[] args){
            new DrawImage();
        }    public void actionPerformed(ActionEvent e) {
            Object o = e.getSource();
            
            if(o.equals(auto)){
                if(auto.isSelected())
                    startAutoRote();
                else
                    stopAutoRote();
            }else{
                if (o.equals(xflip)) {
                    panel.setXFlip();
                } else if (o.equals(yflip)) {
                    panel.setYFlip();
                } else if (o.equals(rotate)) {
                    panel.joinDegree( -90);
                }
                panel.repaint();
            }
        }
        
        private void startAutoRote(){
            if(autoRoteThread == null){
                autoRoteThread = new Thread(autoRote);
                autoRoteThread.start();
            }
        }
        
        private void stopAutoRote(){
            
            if(autoRoteThread.isAlive()){
                autoRoteThread.interrupt();
                autoRoteThread = null ;
            }
        }
        
        class AutoRote implements Runnable{        public void run() {
                while(auto.isSelected()){
                    panel.joinDegree(-90);
                    panel.repaint();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException ex) {
                        
                    }
                }
            }
        }
        
        
        
    }
      

  3. 无聊给你做个
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.*;
    import javax.swing.*;
    import java.awt.geom.*;
    class Test extends JPanel{
    Image img;
    double w,h;
    int ang=0;
    Test(){
    img = new ImageIcon("cat.jpg").getImage();
    w = img.getWidth(null)*0.2;
    h = img.getHeight(null)*0.2;
    }
    public void paintComponent(Graphics g){
    super.paintComponent(g);
    //不知为什么你想画背景再在上面再画个脑袋,想画的下面一句
    ((Graphics2D)g).drawImage(img,0,0,null); AffineTransform trans = new AffineTransform();
    trans.translate((getWidth()-w)/2,(getHeight()-h)/2);
    trans.rotate(Math.PI*ang/180,w/2,h/2);
    trans.scale(0.2,0.2);
    ((Graphics2D)g).setTransform(trans);
    ((Graphics2D)g).drawImage(img,0,0,null);

    }

    public static void main(String[] s){
    JFrame f = new JFrame();
    JPanel p = new JPanel();
    p.setLayout(new BorderLayout());
    final Test t = new Test();
    p.add(t,"Center");
    p.add(new JButton(new AbstractAction("旋转"){
    public void actionPerformed(ActionEvent ae){
    t.ang=(t.ang+90)%360;
    t.repaint();
    }
    }),"South");

    f.setContentPane(p);
    f.setSize(300,330);
    f.setVisible(true);
    }
    }
      

  4. 你这个是缩放的,我也做出来过,其实我主要遇到的问题是想对图片中的局部进行旋转,就像我在提问中示例的哪个区域,一开始使用的是Graphics.createGraphics()方法,结果就出现了我说的问题,而整个区域做翻转我早就做出来了。
      


  5. 这个不至于那么难明白吧?你想想,一张图原本是30x20,旋转90°或者270°以后的图还可能是原来的30x20吗?必然是成了20x30——这跟原始图的尺寸无关,因为原始图的大小始终是30x20,我说的是旋转以后的图,就像我在8楼给出的图片。
      

  6. 想局部啊,cliprectimport java.awt.*;
    import java.awt.event.*;
    import java.awt.image.*;
    import javax.swing.*;
    import java.awt.geom.*;
    class Test extends JPanel{
    Image img;
    int clipw,cliph,clipx,clipy;
    int ang=0;
    Test(){
    img = new ImageIcon("cat.jpg").getImage();
    clipw = 120;
    cliph = 130;
    clipx = clipy=50;
    }
    public void paintComponent(Graphics g){
    super.paintComponent(g);
    //不知为什么你想画背景再在上面再画个脑袋,想画的下面一句
    ((Graphics2D)g).drawImage(img,0,0,null);
    /*
    AffineTransform trans = new AffineTransform();
    trans.translate((getWidth()-clipw)/2,(getHeight()-cliph)/2);
    trans.rotate(Math.PI*ang/180,clipw/2,cliph/2);
    trans.scale(0.2,0.2);
    ((Graphics2D)g).setTransform(trans);
    ((Graphics2D)g).drawImage(img,0,0,null);
    */ ((Graphics2D)g).rotate(Math.PI*ang/180,clipx+clipw/2,clipy+cliph/2);
    g.clipRect(clipx,clipy,clipw,cliph);
    g.drawImage(img,0,0,null);
    }

    public static void main(String[] s){
    JFrame f = new JFrame();
    JPanel p = new JPanel();
    p.setLayout(new BorderLayout());
    final Test t = new Test();
    p.add(t,"Center");
    p.add(new JButton(new AbstractAction("旋转"){
    public void actionPerformed(ActionEvent ae){
    t.ang=(t.ang+90)%360;
    t.repaint();
    }
    }),"South");

    f.setContentPane(p);
    f.setSize(300,330);
    f.setVisible(true);
    }
    }
      

类似问题 »