DELPHI 图片任意角旋转。 我看着书上的C++代码改的,加了点自己的理解。huruihappy
2009-07-07 22:44
525 查看
//============================================================================== //图片旋转 //输入参数 // srcImg : TBitmap 源图 // angle : extended 旋转角度 //输出参数 // result : TBitmap ; 旋转后的图 //作者:胡睿 CSDN: huruihappy. 欢迎访问www.googler.cc 更多惊喜 //QQ : 235483710 //Email : 235483710@qq.com //代码仅限交流 //============================================================================== function TForm1.ImageRotate(srcImg1: TBitmap; angle: extended): TBitmap; var radius, n: integer; alpha: extended; DestBmp : TBitmap ; fRotateAngle : extended ; //弧度 fsrcX1,fsrcX2,fsrcX3,fsrcX4, fsrcY1,fsrcY2,fsrcY3,fsrcY4 : Extended ; //原图4个定点坐标 fDestX1,fDestX2,fDestX3,fDestX4, fDestY1,fDestY2,fDestY3,fDestY4 : Extended ; //目标图4个顶点坐标 fSina,fCosa : Extended ; //旋转角的正弦和余弦值 f1,f2 : Extended ; //常数 coX,coY : Extended ; //输出图像在输入图像中待插值的坐标,必须为浮点 Iu,Iv,i,j,k,t1,t2 : Integer ; begin //作者:胡睿 CSDN: huruihappy. 欢迎访问www.googler.cc 更多惊喜 //QQ : 235483710 //Email : 235483710@qq.com //代码仅限交流 DestBmp := TBitmap.Create ; //将角度转化为弧度 fRotateAngle := Pi * angle / 180 ; //计算旋转角的正弦 fSina := Sin(fRotateAngle) ; //计算旋转角的余弦 fCosa := Cos(fRotateAngle) ; //计算原图4点坐标,以图像中心为坐标原点 fSrcX1 := -( srcImg1.Width - 1 ) / 2 ; fSrcY1 := (srcImg1.Height - 1) / 2 ; fSrcX2 := ( srcImg1.Width - 1 ) / 2 ; fSrcY2 := (srcImg1.Height - 1) / 2 ; fSrcX3 := -( srcImg1.Width - 1 ) / 2 ; fSrcY3 := -(srcImg1.Height - 1) / 2 ; fSrcX4 := ( srcImg1.Width - 1 ) / 2 ; fSrcY4 := -(srcImg1.Height - 1) / 2 ; //计算新图4个角坐标,以图像中心为坐标原点 fDestX1 := fCosa * fSrcX1 + fSina * fSrcY1 ; fDestY1 := -fSina * fSrcX1 + fCosa * fSrcY1 ; fDestX2 := fCosa * fSrcX2 + fSina * fSrcY2 ; fDestY2 := -fSina * fSrcX2 + fCosa * fSrcY2 ; fDestX3 := fCosa * fSrcX3 + fSina * fSrcY3 ; fDestY3 := -fSina * fSrcX3 + fCosa * fSrcY3 ; fDestX4 := fCosa * fSrcX4 + fSina * fSrcY4 ; fDestY4 := -fSina * fSrcX4 + fCosa * fSrcY4 ; //输出后图像宽度和高度 DestBmp.Width := Round( Max( Abs(fDestX4 - fDestX1) , Abs(fDestX3 - fDestX2) ) + 0.5 ) ; DestBmp.Height := Round( Max( Abs(fDestY4 - fDestY1) , Abs(fDestY3 - fDestY2) ) + 0.5 ) ; //计算常数 f1 := -0.5 * (DestBmp.Width - 1) * fCosa + 0.5 * (DestBmp.Height - 1) * fSina + 0.5 * (DestBmp.Width - 1) ; f2 := -0.5 * (DestBmp.Width - 1) * fSina - 0.5 * (DestBmp.Height - 1) * fCosa + 0.5 * (DestBmp.Height - 1) ; //---------------------------------------------------------------------------- //开始旋转 //双线性插值抗锯齿,更好效果可以使用立体卷积(速度奇慢) for i := 0 to DestBmp.Height - 1 do for j := 0 to DestBmp.Width - 1 do begin //输出J,I 映射到原图像坐标 coX := j * fCosa - i * fSina + f1 ; coY := j * fSina + i * fCosa + f2 ; //坐标取整 Iu := Round(coX) ; Iv := Round(coY) ; //判断是否在原图范围内 if ( coX >= 0 ) and ( coX < srcImg1.Width - 1 ) and ( coY >= 0 ) and ( coY < srcImg1.Height - 1 ) then begin if ( Iv >= 1 ) and ( Iv <= srcImg1.Height - 1 ) and ( Iu >= 1 ) and ( Iu <= srcImg1.Width - 1 ) then begin //abcd=(ab+cd) / 2=(A+B+C+D) / 4 //ab= A + (B-A) / 2 //cd=C +(D-C) / 2 //双线性插值 DestBmp.Canvas.Pixels[j,i] := RGB( ( GetRValue( srcImg1.Canvas.Pixels[Iu-1,Iv-1] ) + GetRValue( srcImg1.Canvas.Pixels[Iu+1,Iv-1] ) + GetRValue( srcImg1.Canvas.Pixels[Iu-1,Iv+1] ) + GetRValue( srcImg1.Canvas.Pixels[Iu+1,Iv+1] ) ) div 4 , ( GetGValue( srcImg1.Canvas.Pixels[Iu-1,Iv-1] ) + GetGValue( srcImg1.Canvas.Pixels[Iu+1,Iv-1] ) + GetGValue( srcImg1.Canvas.Pixels[Iu-1,Iv+1] ) + GetGValue( srcImg1.Canvas.Pixels[Iu+1,Iv+1] ) ) div 4 , ( GetBValue( srcImg1.Canvas.Pixels[Iu-1,Iv-1] ) + GetBValue( srcImg1.Canvas.Pixels[Iu+1,Iv-1] ) + GetBValue( srcImg1.Canvas.Pixels[Iu-1,Iv+1] ) + GetBValue( srcImg1.Canvas.Pixels[Iu+1,Iv+1] ) ) div 4 ) ; end else begin //错误点也设置为白色,可替换成背景色 DestBmp.Canvas.Pixels[j,i] := RGB(255,255,255); end ; end else begin //不在原图范围内,则设置为白点 DestBmp.Canvas.Pixels[j,i] := RGB(255,255,255); end ; application.processmessages ; end ; Result := DestBmp ; end;
DELPHI 图片任意角旋转。
我看着书上的C++代码改的,加了点自己的理解。
如果用SCANLINE的话, 速度会提高很多。要用的朋友自己改下吧。
//测试用
Img_Src.Picture.Assign( ImageRotate(Img_Src.Picture.Bitmap , -3 ) ) ;
Img_Src.Picture.SaveToFile('c:/1.bmp');
相关文章推荐
- C++代码实现指针图片旋转功能
- 看着 自己都感觉 恶心的代码,
- 用javascript实现旋转图片效果的代码
- 基于C/C++的读取文件夹下所有文件(图片、文档等)的代码
- 【代码笔记】旋转的图片
- jquery自己主动旋转的登录界面的背景代码登录页背景图
- iOS 图片旋转方法实例代码
- opengl笔记——旋转,一段代码的理解
- 通过代码理解C++虚函数表和多态的实现
- c++Builder图片旋转代码
- OpenCV2.4.13中warpAffine函数理解,旋转,仿射变换,缩放,保持完整图片
- unity中用代码裁剪旋转指定图片
- 看懂下面C++代码才说你理解了C++多态虚函数!
- C#实现图片旋转的代码
- Delphi压缩图片代码
- 看懂下面C++代码才说你理解了C++多态虚函数!
- delphi 图片存数据库的代码
- Android ImageUtils 图片工具类,包括:小米从相册调图像空指针,三星旋转照片,压缩图片,保存Bitmap到本地,获取本地视频的缩略图,毛化玻璃效果,代码以后会更新
- 自己收集整理的 DELPHI 中控制与使用HMTL帮助文件的单元代码。
- 关于C++虚函数自己的理解