/**
創(chuàng)新互聯(lián)是專業(yè)的遠安網(wǎng)站建設(shè)公司,遠安接單;提供網(wǎng)站設(shè)計、成都做網(wǎng)站,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務;采用PHP框架,可快速的進行遠安網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!
?*?旋轉(zhuǎn)圖像為指定角度
?*?
?*?@param?degree
?*?@return
?*/
public?static?BufferedImage?rotateImage(final?Image?image,
final?int?angdeg,?final?boolean?d)?{
int?w?=?image.getWidth(null);
int?h?=?image.getHeight(null);
BufferedImage?img;
Graphics2D?graphics2d;
(graphics2d?=?(img?=?createImage(w,?h,?true))
.createGraphics()).setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2d.rotate(d???-Math.toRadians(angdeg)?:?Math.toRadians(angdeg),
w?/?2,?h?/?2);
graphics2d.drawImage(image,?0,?0,?null);
graphics2d.dispose();
return?img;
}
g.drawImage(rotateImage(image,90,true),?371,?56,?122,?223,?null);
import?java.awt.Canvas;
import?java.awt.Graphics;
import?java.awt.Graphics2D;
import?java.awt.RenderingHints;
import?java.awt.image.BufferedImage;
/**
*?@author?ZhengYesheng
*/
public?class?RotateImageCanvas?extends?Canvas?implements?Runnable
{
private?static?final?long?serialVersionUID?=?-1997487731464495923L;
BufferedImage?img;
BufferedImage?rotatedImg;
int?degress?=?0;
public?RotateImageCanvas(BufferedImage?img)
{
super();
this.img?=?img;
new?Thread(this).start();
}
@Override
public?void?run()
{
while?(true)
{
//A,與B的代碼配合決定旋轉(zhuǎn)的速度
degress?+=?1;
degress?%=?360;
repaint();
try
{
if?(degress?==?0)
{
//繞一周后等待的時間在這里設(shè)置
Thread.sleep(3?*?1000);
}
else
{
//考慮到視覺平滑,這里不應大約40。
Thread.sleep(30);
}
}
catch?(InterruptedException?e)
{
//?TODO?Auto-generated?catch?block
e.printStackTrace();
}
}
}
@Override
public?void?paint(Graphics?graphics)
{
super.paint(graphics);
//獲取旋轉(zhuǎn)指定角度后的圖片。為了避免累計誤差,這里是用原始圖像旋轉(zhuǎn)的
rotatedImg?=?rotateImage(img,?degress);
//繪制旋轉(zhuǎn)后的圖片
graphics.drawImage(rotatedImg,?0,?0,?this);
}
/**
*?旋轉(zhuǎn)圖片為指定角度。
*?注意:1、這個方法實現(xiàn)了圖像的基于中點的旋轉(zhuǎn),要想繞指定點,需要配合Matrix類
*??????????2、為避免圖像被裁切,結(jié)果圖片的尺寸也需要動態(tài)計算
*??????????3、現(xiàn)在旋轉(zhuǎn)后有黑色背景,如果不需要這個效果,需要設(shè)置結(jié)果圖片的Alpha模式
*?
*?@param?bufferedimage
*????????????目標圖像
*?@param?degree
*????????????旋轉(zhuǎn)角度
*?@return
*/
private?BufferedImage?rotateImage(BufferedImage?bufferedimage,?int?degree)
{
int?w?=?bufferedimage.getWidth();
int?h?=?bufferedimage.getHeight();
int?type?=?bufferedimage.getColorModel().getTransparency();
BufferedImage?img;
Graphics2D?graphics2d;
(graphics2d?=?(img?=?new?BufferedImage(w,?h,?type)).createGraphics())
.setRenderingHint(RenderingHints.KEY_INTERPOLATION,?RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2d.rotate(Math.toRadians(degree),?w?/?2,?h?/?2);
graphics2d.drawImage(bufferedimage,?0,?0,?null);
graphics2d.dispose();
return?img;
}
}
在操作二維或三維的圖形圖像上,長期以來人們總結(jié)出了一些常用的變換矩陣,這些矩陣就像公式和定理一樣被開發(fā)人員使用,樓主可以把這些矩陣當成公式來記憶,就像我們小時候背加法、乘法口訣一樣。
如果樓主想了解得更深入一些,請往下看:
[?x']???[??m00??m01??m02??]?[?x?]???[?m00x?+?m01y?+?m02?]
[?y']?=?[??m10??m11??m12??]?[?y?]?=?[?m10x?+?m11y?+?m12?]
[?1?]???[???0????0????1???]?[?1?]???[?????????1?????????]
上面的式子是jdk文檔中復制過來的,就是變換時的運算過程,也就是說變換后的坐標x'、y'是由一個3*3的矩陣與原坐標x、y相乘得出的,其中的m00~m12就是AffineTransform構(gòu)造方法中的六個參數(shù),另外,式子中的最后一行是固定的。
矩陣乘法就不用說了吧,最后得出的結(jié)果就是上式中的最后一列,可能寫成下面這樣會更容易理解:
x'?=?m00x?+?m01y?+?m02
y'?=?m10x?+?m11y?+?m12
看出什么了嗎?其實這就是二維平面直角坐標系中的兩個很簡單的二元一次方程而已,方程定義的就是橫縱坐標變換的規(guī)則。
以水平翻轉(zhuǎn)為例,水平翻轉(zhuǎn)是以圖形/圖像的垂直中線為軸來翻轉(zhuǎn)的,因此任何一個點(x,y)變換后的坐標應該是y坐標不變,x坐標變?yōu)?x+width-1,即(-x+width-1,y),之所以減1是因為垂直中軸上的點不應該改變。
理解了上面的變換過程之后,將結(jié)果帶入上面的兩個二元一次方程,可以得出
m00=-1、m01=0、m02=width-1
m10=0、m11=1、m12=0
正好是你給的代碼中的六個值(AffineTransform構(gòu)造方法中的參數(shù)順序為m00、m10、m01、m11、m02、m12)
其他幾個變換道理是一樣的