Java实现图片翻转以及任意角度旋转
最近几天在做一个项目,因为涉及到了图片(绝大部分都不是整图,是把一张张的大图切成小图,也就是Title)的翻转以及90°旋转,弄得焦头烂额。在网上搜索好几天,发现用到的方法都是比较公式化的,对于只是在绘图的时候需要显示翻转而不需要另外生成图片的情况,这些代码用起来非常的麻烦。最后仔细的研究了一下JDK文档,用Graphics2D很简单的就实现了以下功能:
1、图片的翻转,包括水平翻转以及垂直翻转
2、图片的任意角度旋转。因为工程需要,代码里面都直接写成了+90,根据需要,可以对这个值进行改动,以符合需求。
3、可以使用组合操作,比如水平翻转+旋转,或者垂直+水平+旋转,任意。
以下是代码:
packageDemo628;
importjava.awt.*;
importjava.awt.event.*;
importjava.util.*;
importjavax.swing.*;
publicclassImageRote
{
publicstaticvoidmain(String[]args)
{
JFrameframe=newTransformFrame();
frame.setVisible(true);
}
}
classTransformFrameextendsJFrameimplementsActionListener
{
//添加几个按钮方便操作。
JButtonrote=newJButton("旋转");
JButtonflipX=newJButton("水平翻转");
JButtonflipY=newJButton("垂直翻转");
JButtonzoomIn=newJButton("放大");
JButtonzoomOut=newJButton("缩小");
publicTransformFrame()
{
setTitle("TransformTest");
setSize(400,400);
addWindowListener(newWindowAdapter()
{
publicvoidwindowClosing(WindowEvente)
{
System.exit(0);
}
});
ContainercontentPane=getContentPane();
canvas=newTransPanel();
contentPane.add(canvas,"Center");
JPanelbuttonPanel=newJPanel();
buttonPanel.add(rote);
rote.addActionListener(this);
buttonPanel.add(flipX);
flipX.addActionListener(this);
buttonPanel.add(flipY);
flipY.addActionListener(this);
buttonPanel.add(zoomIn);
zoomIn.addActionListener(this);
buttonPanel.add(zoomOut);
zoomOut.addActionListener(this);
contentPane.add(buttonPanel,"North");
}
publicvoidactionPerformed(ActionEventevent)
{
Objectsource=event.getSource();
//对于source==???这种方法,在特殊的情况下出现错误,所以,需要酌情使用event.getSource().equals()方法来替代==
if(source==rote)
{
canvas.setRotate();
}else
if(source==flipX)
{
canvas.flipX();
}else
if(source==flipY)
{
canvas.flipY();
}else
if(source==zoomIn)
{
canvas.zoomIn();
}else
if(source==zoomOut)
{
canvas.zoomOut();
}
}
privateTransPanelcanvas;
}
classTransPanelextendsJPanel
{
//水平翻转比例的标志。-1表示需要进行水平翻转
intm_nFlipXScale=1;
//垂直翻转比例的标志。-1表示需要进行垂直翻转
intm_nFlipYScale=1;
//旋转的角度。因为工程需要,代码中直接写成了90,可以根据具体需要动态修改,以符合实际情况
introteAngle=0;
//缩放比例。默认的比例0表示没有翻转,具体的翻转大小通过一个方法:getZoomSize()获取
intzoomLevel=0;
publicTransPanel()
{
//首先载入一张图片。
img=newImageIcon("D000.GIF").getImage();
}
publicvoidpaintComponent(Graphicsg)
{
super.paintComponent(g);
g.drawImage(img,0,0,this);
drawTransImage(g,img.getWidth(this),img.getHeight(this),zoomLevel);
}
publicvoiddrawTransImage(Graphicsg,intdrawx,intdrawy,intzoom)
{
intx=0;
inty=0;
intw=img.getWidth(this);
inth=img.getHeight(this);
intzoomw=getZoomSize(w,zoom);
intzoomh=getZoomSize(h,zoom);
intxPos=0;
intyPos=0;
if(m_nFlipXScale==-1)
xPos=-zoomw;
if(m_nFlipYScale==-1)
yPos=-zoomh;
Graphics2Dg2=(Graphics2D)g;
//转换坐标原点。这步不要也成,但是将当前位置转换为坐标原点后,可以节省好多计算步骤,非常好用。
//不过记得用完了以后,一定要把原点转换回来,要不然其他地方就乱了
g2.translate(drawx,drawy);
if(roteAngle!=0)
g2.rotate(Math.toRadians(m_nFlipXScale*m_nFlipYScale*roteAngle),zoomw>>1,zoomh>>1);
//上面的m_nFlipXScale*m_nFlipYScale需要特殊说明一下:因为实际使用中,可能遇到各种组合的情况,比如
//先flipX或者flipY以后然后再旋转,这时候,图片的旋转方向就会出现错误,加上这段代码可以保证无论使用哪种组合
//操作方式,都保证在旋转图片的时候是按照顺时针的方向进行旋转。
if(m_nFlipXScale==-1)
g2.scale(-1,1);//第一个值表示水平,-1表示等宽水平翻转,Math.abs(m_nFlipXScale)的值越大,出来的图片就越宽
if(m_nFlipYScale==-1)
g2.scale(1,-1);//第二个值表示垂直,-1表示等高垂直翻转,Math.abs(m_nFlipYScale)的值越大,出来的图片就越高
//显示图片
g2.drawImage(img,xPos,yPos,xPos+zoomw,yPos+zoomh,x,y,w,h,null);
g2.translate(-drawx,-drawy);
}
publicvoidsetRotate()
{
roteAngle+=90;
roteAngle%=360;
repaint();
}
publicvoidflipX()
{
m_nFlipXScale=-m_nFlipXScale;
repaint();
}
publicvoidflipY()
{
m_nFlipYScale=-m_nFlipYScale;
repaint();
}
publicvoidzoomIn()
{
zoomLevel++;
repaint();
}
publicvoidzoomOut()
{
zoomLevel--;
repaint();
}
publicstaticfinalintgetZoomSize(intsourceSize,intzoomLevel)
{
if(zoomLevel==0)
returnsourceSize;
else
if(zoomLevel<0)
returnsourceSize/(Math.abs(zoomLevel)+1);
else
returnsourceSize*(zoomLevel+1);
}
privateImageimg;
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。