Java实现图片翻转以及任意角度旋转

时间:2022-09-22 20:14:44

最近几天在做一个项目,因为涉及到了图片(绝大部分都不是整图,是把一张张的大图切成小图,也就是title)的翻转以及90°旋转,弄得焦头烂额。在网上搜索好几天,发现用到的方法都是比较公式化的,对于只是在绘图的时候需要显示翻转而不需要另外生成图片的情况,这些代码用起来非常的麻烦。最后仔细的研究了一下jdk文档,用graphics2d很简单的就实现了以下功能:

1、图片的翻转,包括水平翻转以及垂直翻转
2、图片的任意角度旋转。因为工程需要,代码里面都直接写成了+90,根据需要,可以对这个值进行改动,以符合需求。

3、可以使用组合操作,比如水平翻转+旋转,或者垂直+水平+旋转,任意。

以下是代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package demo628;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
 
public class imagerote
{
 public static void main(string[] args)
 {
  jframe frame = new transformframe();
  frame.setvisible(true);
 }
}
 
class transformframe extends jframe implements actionlistener
{
 //添加几个按钮方便操作。
 jbutton rote = new jbutton("旋转") ;
 jbutton flipx= new jbutton("水平翻转");
 jbutton flipy= new jbutton("垂直翻转");
 jbutton zoomin = new jbutton("放大") ;
 jbutton zoomout = new jbutton("缩小") ;
 public transformframe()
 {
  settitle("transformtest");
  setsize(400, 400);
  addwindowlistener(new windowadapter()
  {
   public void windowclosing(windowevent e)
   {
    system.exit(0);
   }
  });
  container contentpane = getcontentpane();
  canvas = new transpanel();
  contentpane.add(canvas, "center");
  jpanel buttonpanel = new jpanel();
  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");
 }
 
 public void actionperformed(actionevent event)
 {
  object source = 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();
  }
 }
 private transpanel canvas;
}
 
class transpanel extends jpanel
{
 //水平翻转比例的标志。-1表示需要进行水平翻转
 int m_nflipxscale = 1 ;
 //垂直翻转比例的标志。-1表示需要进行垂直翻转
 int m_nflipyscale = 1 ;
 //旋转的角度。因为工程需要,代码中直接写成了90,可以根据具体需要动态修改,以符合实际情况
 int roteangle = 0 ;
 //缩放比例。默认的比例0表示没有翻转,具体的翻转大小通过一个方法:getzoomsize()获取
 int zoomlevel = 0 ;
 public transpanel()
 {
  //首先载入一张图片。
  img = new imageicon("d000.gif").getimage();
 }
 public void paintcomponent(graphics g)
 {
  super.paintcomponent(g);
  g.drawimage(img,0,0,this) ;
  
  drawtransimage(g,img.getwidth(this),img.getheight(this),zoomlevel) ;
  
 }
 
 public void drawtransimage(graphics g,int drawx,int drawy,int zoom)
 {
  int x = 0 ;
  int y = 0 ;
  int w = img.getwidth(this) ;
  int h = img.getheight(this) ;
  int zoomw = getzoomsize(w,zoom) ;
  int zoomh = getzoomsize(h,zoom) ;
  int xpos = 0 ;
  int ypos = 0 ;
  if (m_nflipxscale == -1)
    xpos = -zoomw ;
  if (m_nflipyscale == -1)
    ypos = -zoomh ;
  graphics2d g2 = (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); 
 }
 public void setrotate()
 {
  roteangle += 90 ;
  roteangle %= 360 ;
  repaint();
 }
 public void flipx()
 {
  m_nflipxscale = -m_nflipxscale ;
  repaint();
 }
 
 public void flipy()
 {
  m_nflipyscale = -m_nflipyscale ;
  repaint();
 }
 
 public void zoomin()
 {
  zoomlevel++ ;
  repaint();
 }
 
 public void zoomout()
 {
  zoomlevel-- ;
  repaint();
 }
 
 public static final int getzoomsize(int sourcesize,int zoomlevel)
 {
  if (zoomlevel == 0)
    return sourcesize ;
  else
  if (zoomlevel < 0)
   return sourcesize / (math.abs(zoomlevel) + 1) ;
  else
   return sourcesize * (zoomlevel + 1) ;
  }
 private image img;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/wyg_vip/article/details/4109261