问题就是,当我旋转的度数不是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();
}
}
原始图
旋转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();
}
}
g2d.fillRect(0,0,116,160); 会不会也得跟着变呢?
可以看到,每次旋转的时候,图像的宽高都发生了变化。以下是更改以后的代码,旋转的角度我写成了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) {
}
}
}
}
}
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);
}
}
这个不至于那么难明白吧?你想想,一张图原本是30x20,旋转90°或者270°以后的图还可能是原来的30x20吗?必然是成了20x30——这跟原始图的尺寸无关,因为原始图的大小始终是30x20,我说的是旋转以后的图,就像我在8楼给出的图片。
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);
}
}