想使某个picturebox内已加载的图像实现任意给定角度的旋转,旋转后的图像仍然显示在原有picturebox内,也就是说相当于用旋转后的图像覆盖旋转前的图像,现在旋转的算法已有,关键就是如何实现覆盖了,望各位大大给小弟些指点~

解决方案 »

  1.   

    经过楼上高人指点,目前做到的程度是将一个picturebox内的图像旋转任意角度,然后在另一个picturebox内显示出来,可我还是想最好可以在同一个picturebox内显示旋转后的图像,还是没有头绪,期待高人ing ~~~
      

  2.   

    首先,你的容器要随着图像的旋转改变而改变大小,然后就是如果你一定要先在picturebox中显示图像,则第一次调用旋转后调用picture1.picture=LoadPicture(),然后每次旋转后在bitblt到容器上。
      

  3.   

    你看人家ZYL910的那个旋转是如何实现覆盖的啊
      

  4.   

    有些茫然,貌似要用到getobject把图像读入内存,旋转完成后再从内存中读出显示?期待达人给出更详细方法和步骤
      

  5.   

    再次路过~~清空 PictureBox 内容:
    Picture1.Picture = LoadPicture("")针对楼主在楼上的发言,建议还是去多看看有关 Windows 图像这部分的内容。主要是明确 DDB 和 DIB 的概念。其实用 DDB 完全可以解决,“把图像读入内存”是 DIB 或 DIB Section 的概念。还是简略说一下操作步骤吧:
    先建立缓存 DC,再建立一个 BMP 对象,其尺寸根据原来 PictureBox 里图片的尺寸和旋转角度计算得出,把这个 BMP 选入 DC;
    用 BitBlt 把 PictureBox 场景里的位图拷贝到缓存 DC;
    清空 PictureBox;
    用 StretchBlt 直接把缓存 DC 里的位图做镜像旋转到PictureBox 即可。涉及到的 API 函数:
    Private Declare Function CreateCompatibleBitmap Lib "gdi32" Alias "CreateCompatibleBitmap" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
    Private Declare Function CreateCompatibleDC Lib "gdi32" Alias "CreateCompatibleDC" (ByVal hdc As Long) As Long
    Private Declare Function SelectObject Lib "gdi32" Alias "SelectObject" (ByVal hdc As Long, ByVal hObject As Long) As Long
    Private Declare Function DeleteObject Lib "gdi32" Alias "DeleteObject" (ByVal hObject As Long) As Long
    Private Declare Function BitBlt Lib "gdi32" Alias "BitBlt" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
    Private Declare Function StretchBlt Lib "gdi32" Alias "StretchBlt" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
    Private Declare Function SetStretchBltMode Lib "gdi32" Alias "SetStretchBltMode" (ByVal hdc As Long, ByVal nStretchMode As Long) As Long
    Private Declare Function DeleteDC Lib "gdi32" Alias "DeleteDC" (ByVal hdc As Long) As Long
      

  6.   

    原来是这样,那能否麻烦楼上给个类似的例子让小弟参考下呢,除了bitblt和stretchblt,其他的函数还是第一次接触
      

  7.   

    工程窗体上添加一个按钮:cmd1
    两个PictureBox ,名字分别为 picSrc 和 picDst
    下面是代码,已经运行通过。Option ExplicitPrivate Declare Function PlgBlt Lib "gdi32" ( _
      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
    Private Type POINTAPI
      x As Long
      y As Long
    End Type
    Private Type Size
      cx As Long
      cy As Long
    End TypePrivate Declare Function GetObjectAPI& Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any)
    Private Type BITMAP  '14 bytes
      bmType As Long
      bmWidth As Long
      bmHeight As Long
      bmWidthBytes As Long
      bmPlanes As Integer
      bmBitsPixel As Integer
      bmBits As Long
    End TypePrivate Const cPi = 3.14159265358979
    Private nAngle As Single  '单位:角度
    Private tSrcSize As SizePrivate Sub Form_Load()
      picSrc.AutoRedraw = True
      picDst.AutoRedraw = True
      picDst.BorderStyle = 0
      picSrc.Picture = LoadPicture("这里添加图片路径")
      
      '得到 picSrc 图片的长、宽
      Dim tBmp As BITMAP
      Call GetObjectAPI&(picSrc.Picture.Handle, Len(tBmp), tBmp)
      tSrcSize.cx = tBmp.bmWidth
      tSrcSize.cy = tBmp.bmHeight  '设定旋转角度,这个可以在程序中根据实际情况设定。
      '这里作为演示,设为30度
      nAngle = 30
    End SubPrivate Sub cmd1_Click()
      Dim tPoint(2) As POINTAPI
      Dim tDstSize As Size '旋转后的新尺寸
      Dim nRadian As Single 'nAngle 换算为弧度
      
      nRadian = nAngle * (cPi / 180)
      tDstSize.cx = CLng(tSrcSize.cx * Cos(nRadian) + tSrcSize.cy * Sin(nRadian))
      tDstSize.cy = CLng(tSrcSize.cx * Sin(nRadian) + tSrcSize.cy * Cos(nRadian))  tPoint(0).x = 0: tPoint(0).y = CLng(tSrcSize.cx * Sin(nRadian))
      tPoint(1).x = CLng(tSrcSize.cx * Cos(nRadian)): tPoint(1).y = 0
      tPoint(2).x = CLng(tSrcSize.cy * Sin(nRadian)): tPoint(2).y = tDstSize.cy
      
      picDst.Width = Me.ScaleX(tDstSize.cx, vbPixels, vbTwips)
      picDst.Height = Me.ScaleY(tDstSize.cy, vbPixels, vbTwips)
      Call PlgBlt(picDst.hDC, tPoint(0), picSrc.hDC, 0, 0, tSrcSize.cx, tSrcSize.cy, 0&, 0&, 0&)
      picDst.Refresh
    End Sub
      

  8.   

    补充一下,出于精简和满足多次旋转的考虑,上面的例程没有使用内存 DC,而是用一个 PictureBox 来存储源图片的。
      

  9.   

    你好。能把你那程序发给我参考一下吗?谢谢。[email protected]