CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VB >  基础类

如何实现图片文件的旋转问题?

楼主nofound007(★★★ 天堂小鱼儿 ★★★)2005-11-04 08:39:28 在 VB / 基础类 提问

在VB里如何实现图片文件旋转,就像在ACDSEE里对图片进行旋转90°、180°、270°,同时重新将新文件保存到该图片里(即覆盖原文件),如何实现? 问题点数:50、回复次数:17Top

1 楼Gujianda(朝成暮毁,越学越怕!)回复于 2005-11-04 08:45:01 得分 0

不清楚你的用意,三星级的资历应该会完成这个旋转算法问题吧。  
  我想难度在各类图像文件的解压缩/压缩算法上。  
  Top

2 楼VBToy(无证编程)回复于 2005-11-04 08:47:41 得分 0

 
  VB中位图旋转的实现  
   
  在VISUAL   BASIC中没有什么命令或函数能够实现将一个位图旋转一个角度后显示出来,但我们可以用画点的方式,将一个图画盒中的位图中的像素点旋转一个角度后画入另一个图画盒中,当源图画盒中的像素都被画到目标图画盒中时,也就完成了位图的旋转。这里主要用到了VISUAL   BASIC中的两个方法:POINT方法和PSET方法。POINT方法的作用是从源图画盒中提取一个像素点的颜色值;而PSET方法的作用是按照旋转后的坐标和相应像素点的颜色值在目标图画盒中画点。显然这个方法的速度不会太快,因而适用于较小的图片。  
   
  下面介绍一下实现方法:进入VISUAL   BASIC中,建立一个新的窗体。在窗体中加入两个图画盒控件(Picture1和Picture2),设置它们的Name属性为PicSource和PicTarget,并为PicSource图画盒的Picture属性设置一幅位图。再在窗体中加入一个按钮(CommandRotorate),设置它的Caption属性为“旋转”。然后加入以下代码:  
  Option   Explicit  
  Const   Pi   =   3.14  
  Private   Sub   CommandRototate_Click()  
  Dim   x   As   Integer,   y   As   Integer  
  Dim   X1   As   Integer,   Y1   As   Integer  
  Dim   X2   As   Double,   Y2   As   Double  
  Dim   X3   As   Double,   Y3   As   Double  
  Dim   JiaoDu   As   Double  
  Dim   HuDu   As   Double  
  JiaoDu   =   45   '角度  
  HuDu   =   JiaoDu   *   Pi   /   180   '弧度  
  PicSource.ScaleMode   =   vbPixels  
  PicTarget.ScaleMode   =   vbPixels  
  For   x   =   0   To   PicTarget.ScaleWidth  
  X1   =   x   -   PicTarget.ScaleWidth   \   2  
  For   y   =   0   To   PicTarget.ScaleHeight  
  Y1   =   y   -   PicTarget.ScaleHeight   \   2  
  X2   =   X1   *   Cos(-HuDu)   +   Y1   *   Sin(-HuDu)  
  Y2   =   Y1   *   Cos(-HuDu)   -   X1   *   Sin(-HuDu)  
  X3   =   X2   +   PicSource.ScaleWidth   \   2  
  Y3   =   Y2   +   PicSource.ScaleHeight   \   2  
  If   X3   >   0   And   X3   <   PicSource.ScaleWidth   -   1   And   Y3   >   0   And   Y3   <    
  PicSource.ScaleHeight   -   1   Then  
  PicTarget.PSet   (x,   y),   PicSource.Point(X3,   Y3)  
  End   If  
  Next   y  
  Next   x  
  End   Sub  
  运行后,按下“旋转”按钮,可以见到源图画盒中的位图旋转45度后进入到目标图画盒中。如果要改变旋转的角度,只需将JiaoDu变量设置为相应值即可。Top

3 楼rainstormmaster(暴风雨 v2.0)回复于 2005-11-04 09:18:05 得分 0

什么系统,2000以上的系统可以试试api函数PlgBlt,他可以实现位图的旋转:  
   
  【声明】  
  Private   Declare   Function   PlgBlt   Lib   "gdi32"   Alias   "PlgBlt"   (ByVal   hdcDest   As   Long,   lpPoint   As   POINTAPI,   ByVal   hdcSrc   As   Long,   ByVal   nXSrc   As   Long,   ByVal   nYSrc   As   Long,   ByVal   nWidth   As   Long,   ByVal   nHeight   As   Long,   ByVal   hbmMask   As   Long,   ByVal   xMask   As   Long,   ByVal   yMask   As   Long)   As   Long  
   
  【说明】  
      复制一幅位图,同时将其转换成一个平行四边形。利用它可对位图进行旋转处理    
   
  【返回值】  
      Long,非零表示成功,零表示失败。会设置GetLastError    
   
  【备注】  
      如果对源图象应用了旋转或剪切处理,这个函数的执行就会失败。可用GetDeviceCaps判断这个函数是否得到了一个特定设备场景的支持  
   
  【参数表】  
      hdcDest   --------     Long,图象使用的目标设备场景  
   
      lpPoint   --------     POINTAPI,POINTAPI结构数组中使用的第一个条目。第一个点对应于一个平行四边形左上角位置;第二个点代表右下角位置;第三个点代表左下角位置;第四个点是在前三个点的基础上导出的  
   
      hdcSrc   ---------     Long,图象的源设备场景  
   
      nXSrc,nYSrc   ----     Long,源图象左上角的x,y坐标,采用逻辑坐标系统表示  
   
      nWidth,nHeight   -     Long,源图象大小,用逻辑坐标表示  
   
      hbmMask   --------     Long,一个可选的句柄,指向一个单色掩模。如设定了这个参数,那么只有与掩模值1对应的二进制位才会传输到目的地  
   
      xMask,yMask   ----     Long,掩模位图欲使用区域左上角的x,y坐标  
      适用平台  
      Windows   NT  
   
  Top

4 楼Summer006(脸都丢尽了!闭关修练。。。。)回复于 2005-11-04 09:40:48 得分 0

哦呵呵。90度整数倍的旋转简单的很嘛。最多就是图像宽高交替一下。  
  用一个循环转换一下坐标就是了。,x变成y,或者x变成width-x。  
   
  任意角度就要sin,cos这些了。还要原点。。比较麻烦,楼上的朋友也贴了,可以参考  
  Top

5 楼nofound007(★★★ 天堂小鱼儿 ★★★)回复于 2005-11-04 10:56:08 得分 0

仅旋转当然简单,我把旋转后的文件保存到文件中去啊……Top

6 楼nofound007(★★★ 天堂小鱼儿 ★★★)回复于 2005-11-04 10:56:24 得分 0

当然要保证不失真!!!Top

7 楼pcm112(独孤成明)回复于 2005-11-04 11:05:17 得分 0

可以试试用微软的ijl11.dllTop

8 楼pcm112(独孤成明)回复于 2005-11-04 11:06:48 得分 0

http://www.vbaccelerator.com/codelib/gfx/vbjpeg.htmTop

9 楼nofound007(★★★ 天堂小鱼儿 ★★★)回复于 2005-11-04 11:44:50 得分 0

应该不用这么复杂吧;Top

10 楼WallesCai(女人之美,在于蠢得无怨无悔,男人之美,在于撒谎撒得白日见鬼)回复于 2005-11-04 11:53:29 得分 0

楼主这个问题其实包含了两个问题:  
   
  1:图像旋转:这个可以用API或者画点的方法解决  
   
  2:图像保存:VB只能保存BMP,如果是其他类型,可以用GDI+等方法来实现。  
   
  Top

11 楼Summer006(脸都丢尽了!闭关修练。。。。)回复于 2005-11-04 11:57:33 得分 0

你要能做到把图片的每点颜色读到内存中数组里,就成功1/3了。  
  再对这个数组进行处理转换,你就是一个旋转,这里比较简单。   2/3了。  
  再把转换后的数组写入原图片里边,完了。  
   
  哪步有问题啊?  
   
  ps:据我所知vb里面图像处理的3种基本方法,按效率从高到低,也是难度从难到易排:  
  SafeArray2D()     和CopyMemory配合使用  
  GetDIBits()       是这样写吗?忘了  
  picturebox控件   的point   ,pset方法  
   
  不知道有没有更快的方法?lz用的哪种?Top

12 楼lxcy(始经天月照,终若流星驰!)回复于 2005-11-04 13:58:09 得分 0

api就可以了Top

13 楼nofound007(★★★ 天堂小鱼儿 ★★★)回复于 2005-11-04 17:24:23 得分 0

API举个例子……???Top

14 楼Gujianda(朝成暮毁,越学越怕!)回复于 2005-11-06 09:02:59 得分 0

上面的红星老大们,请说说,对于有压缩的图像,旋转过程中不牵涉到压缩计算问题吗?  
  我不懂,但想想没那么简单。旋转问题有什么好讨论的,学过高中解析几何的就该会!Top

15 楼nofound007(★★★ 天堂小鱼儿 ★★★)回复于 2006-01-10 23:15:38 得分 0

1     谁说VB不能转,我转,我转,我转转      
      前些时候和朋友交流图片旋转的问题,朋友讲VB做图片旋转根本是开玩笑,速度根本跟不上,我就不信这个邪,经过N长时间搜罗资料,终于得到了下面的方法,DIB法,其实我们处理图片速度慢不是VB慢,而是你的方法有问题,所以写到这里大家共同研究一下:    
  一个Module    
  Type   BITMAPINFOHEADER   '40   bytes,这个大家可以看看BMP的格式    
          BmSize   As   Long    
          BmWidth   As   Long    
          BmHeight   As   Long    
          BmPlanes   As   Integer    
          BmBitCount   As   Integer    
          BmCompression   As   Long    
          BmSizeImage   As   Long    
          BmXPelsPerMeter   As   Long    
          BmYPelsPerMeter   As   Long    
          BmClrUsed   As   Long    
          BmClrImportant   As   Long    
          End   Type    
   
   
  Type   BITMAPINFO    
          BmHeader   As   BITMAPINFOHEADER    
          End   Type    
  '下面是两个操作DIB的函数    
  Declare   Sub   GetDIBits   Lib   "GDI32"   (ByVal   hDC&,   ByVal   hBitmap&,   ByVal   nStartScan&,   ByVal   nNumScans&,   lpBits   As   Any,   lpBI   As   BITMAPINFO,   ByVal   wUsage&)    
   
   
  Declare   Sub   SetDIBits   Lib   "GDI32"   (ByVal   hDC&,   ByVal   hBitmap&,   ByVal   nStartScan&,   ByVal   nNumScans&,   lpBits   As   Any,   lpBI   As   BITMAPINFO,   ByVal   wUsage&)    
   
  下面是窗体部分,两个Picture,Picture1装载一个图片,要小点的哦,呵呵,Picture2显示旋转结果,一个HScroll    
  ,下面是代码:    
  Sub   RotatePicDI(SrcPic   As   PictureBox,   DestPic   As   PictureBox,   A   As   Double)    
          Dim   SrcInfo   As   BITMAPINFO,   DesInfo   As   BITMAPINFO    
          Dim   X&,   Y&,   CA   As   Double,   SA   As   Double,   nX&,   nY&    
          Dim   sW&,   sH&,   sW2&,   sH2&,   dW&,   dH&,   dW2&,   dH2&    
          Const   Pi   =   0.017453292519943    
          CA   =   Cos(A   *   Pi   *   -1):   SA   =   Sin(A   *   Pi   *   -1)    
          sW   =   SrcPic.ScaleWidth    
          sH   =   SrcPic.ScaleHeight    
          dW   =   DestPic.ScaleWidth    
          dH   =   DestPic.ScaleHeight    
          sW2   =   sW   /   2:   sH2   =   sH   /   2    
          dW2   =   dW   /   2:   dH2   =   dH   /   2    
          SrcInfo.BmHeader.BmSize   =   40    
          SrcInfo.BmHeader.BmWidth   =   sW    
          SrcInfo.BmHeader.BmHeight   =   -sH    
          SrcInfo.BmHeader.BmPlanes   =   1    
          SrcInfo.BmHeader.BmBitCount   =   32    
          SrcInfo.BmHeader.BmSizeImage   =   3   *   sW   *   sH    
          LSet   DesInfo   =   SrcInfo    
          DesInfo.BmHeader.BmWidth   =   dW    
          DesInfo.BmHeader.BmHeight   =   -dH    
          DesInfo.BmHeader.BmSizeImage   =   3   *   dW   *   dH    
          ReDim   SrcPix(0,   sW   -   1,   sH   -   1)   As   Long    
          ReDim   DesPix(0,   dW   -   1,   dH   -   1)   As   Long    
          Call   GetDIBits(SrcPic.hDC,   SrcPic.Image,   0&,   sH,   SrcPix(0,   0,   0),   SrcInfo,   0&)    
          For   Y   =   0   To   dH   -   1    
                  For   X   =   0   To   dW   -   1    
                          nX   =   CA   *   (X   -   dW2)   -   SA   *   (Y   -   dH2)   +   sW2    
                          nY   =   SA   *   (X   -   dW2)   +   CA   *   (Y   -   dH2)   +   sH2    
                          If   nX   >   -1   And   nY   >   -1   And   nX   <   sW   And   nY   <   sH   Then    
                                  DesPix(0,   X,   Y)   =   SrcPix(0,   nX,   nY)    
                          End   If    
                  Next    
          Next    
          Call   SetDIBits(DestPic.hDC,   DestPic.Image,   0&,   dH,   DesPix(0,   0,   0),   DesInfo,   0&)    
          DestPic.Picture   =   DestPic.Image    
  End   Sub    
   
  Private   Sub   HScroll1_Scroll()    
  RotatePicDI   Picture1,   Picture2,   HScroll1.Value    
  End   Sub    
  拖动HScroll1看看结果吧      
     
         
      作者:   Deane·King     2005-12-30   10:16       回复此发言          
       
  Top

16 楼guoguo1982(蝈蝈)回复于 2006-01-11 09:50:14 得分 0

学习中Top

17 楼yangyangyy(逍遥公主)回复于 2006-01-11 17:01:08 得分 0

VB调用缩略图水印组件wsImage3.5   中的支持图片任意角度旋转功能即可。  
  www.wave12.comTop

相关问题

  • 图片旋转
  • 如何实现鼠标拖动旋转image图片?-----请指点
  • 在网页上如何实现图片旋转效果??
  • 请问我想让一张图片旋转该怎样实现?
  • 如何实现图片旋转的动作过程
  • 在Vb中实现图片的任意角度的旋转旋转(满屏的大图片)?
  • 腾讯浏览器的bmp文件是怎么实现旋转播放的
  • 如何实现:几张图片->一个文件
  • 请问用ASP怎么实现图片文件上传?
  • 怎么实现图片的任意方向.任意角度的旋转?

关键词

  • 文件
  • 像素
  • 属性
  • 旋转
  • hudu
  • pictarget
  • 图画盒中
  • picsource
  • doubledim
  • 窗体

得分解答快速导航

  • 帖主:nofound007

相关链接

  • Visual Basic类图书
  • Visual Basic类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo