关于PlgBlt旋转图像问题

lzqgj 2010-05-31 08:50:11
TurnPic Me, Picture1, Picture1, 1 '调用旋转处理函数,旋转1度

Public Function TurnPic(ByVal ObjMe As Object, ByVal pObj1 As Object, ByVal pObj2 As Object, ByVal dThetaDeg As Double)
Dim pt(1 To 3) As POINTAPI, p4 As POINTAPI
Dim dx As Long, dy As Long
Dim I As Long, offsetX As Long, offsetY As Long
Dim Sida As Double
Dim MaxX As Long, MaxY As Long, MinX As Long, MinY As Long

Sida = dThetaDeg * PI / 180

dx = ObjMe.ScaleX(pObj1.Picture.width, vbHimetric, vbPixels)
dy = ObjMe.ScaleX(pObj1.Picture.height, vbHimetric, vbPixels)

pt(1).x = dy * Sin(Sida)
pt(1).y = dy - dy * Cos(Sida)
pt(2).x = pt(1).x + dx * Cos(Sida)
pt(2).y = pt(1).y + dx * Sin(Sida)
pt(3).x = 0: pt(3).y = dy

'p4不用在pt()之阵列,它是由pt(1)-pt(3)所推出
p4.x = pt(3).x + dx * Cos(Sida)
p4.y = pt(3).y + dx * Sin(Sida)

I = PlgBlt(pObj2.hdc, pt(1), pObj1.hdc, 0, 0, dx, dy, 0, 0, 0)
pObj2.Refresh
End Function


运行发现旋转角度超过3°时显示正常,但1°、2°变形十分严重,基本看不出原来图像的模样了。请指教原因在哪。
...全文
593 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
lzqgj 2010-06-01
  • 打赏
  • 举报
回复
对比程序用GDI和GDI+的坐标参数,好像都是一样的。为什么GDI+的结果是倒转而且是背面的呢?

GDI的参数:
xPos = NewWidth / 2: yPos = NewHeight / 2 '新的中心点
Points(0).x = -OldWidth * 0.5
Points(0).y = -OldHeight * 0.5
Points(1).x = Points(0).x + OldWidth
Points(1).y = Points(0).y
Points(2).x = Points(0).x
Points(2).y = Points(0).y + OldHeight
RotatePoints(0).x = (Points(0).x * CosAngle - Points(0).y * SinAngle) + xPos
RotatePoints(0).y = (Points(0).x * SinAngle + Points(0).y * CosAngle) + yPos
RotatePoints(1).x = (Points(1).x * CosAngle - Points(1).y * SinAngle) + xPos
RotatePoints(1).y = (Points(1).x * SinAngle + Points(1).y * CosAngle) + yPos
RotatePoints(2).x = (Points(2).x * CosAngle - Points(2).y * SinAngle) + xPos
RotatePoints(2).y = (Points(2).x * SinAngle + Points(2).y * CosAngle) + yPos
PlgBlt Me.hDC, RotatePoints(0), SrcDib.hDC, 0, 0, OldWidth, OldHeight, 0, 0, 0
GDI+的参数:
xPos = NewWidth / 2: yPos = NewHeight / 2 '新的中心点
Points(0).x = -OldWidth * 0.5
Points(0).y = -OldHeight * 0.5
Points(1).x = Points(0).x + OldWidth
Points(1).y = Points(0).y
Points(2).x = Points(0).x
Points(2).y = Points(0).y + OldHeight
RotatePoints(0).x = (Points(0).x * CosAngle - Points(0).y * SinAngle) + xPos
RotatePoints(0).y = (Points(0).x * SinAngle + Points(0).y * CosAngle) + yPos
RotatePoints(1).x = (Points(1).x * CosAngle - Points(1).y * SinAngle) + xPos
RotatePoints(1).y = (Points(1).x * SinAngle + Points(1).y * CosAngle) + yPos
RotatePoints(2).x = (Points(2).x * CosAngle - Points(2).y * SinAngle) + xPos
RotatePoints(2).y = (Points(2).x * SinAngle + Points(2).y * CosAngle) + yPos
uInput.GdiplusVersion = 1
GdiplusStartup token, uInput
GdipCreateFromHDC Me.hDC, graphics
GdipSetPixelOffsetMode graphics, PixelOffsetModeHalf
GdipCreateBitmapFromScan0 SrcDib.Width, SrcDib.Height, SrcDib.WidthBytes, &H22009, ByVal SrcDib.DataPtr, Img

GdipSetInterpolationMode graphics, InterpolationModeHighQualityBicubic

GdipDrawImagePointsRectI graphics, Img, RotatePoints(0), 3, 0, 0, SrcDib.Width, SrcDib.Height, 2, 0, 0, 0
GdipDeleteGraphics graphics

GdipDisposeImage Img
GdiplusShutdown token
能不能指点一下应该在哪里修改?
lzqgj 2010-06-01
  • 打赏
  • 举报
回复
已经很好了。有点锯齿还是可以接受的。就是倒转的坐标处理还需要学习一下。
还有就是不能打开tif文件,可惜了
lzqgj 2010-06-01
  • 打赏
  • 举报
回复
非常感谢!效果很好。
那个cimage插件太好用了,直接可以做到旋转效果,而且基本没有锯齿。
laviewpbt 2010-06-01
  • 打赏
  • 举报
回复
laviewpbt 2010-05-31
  • 打赏
  • 举报
回复
PlgBlt无法实现抗锯齿效果的旋转,用GDI+的相关函数旋转图像的效果能使图像内部完美抗锯齿,但是对于图像的四个边缘至少有一个边无法抗锯齿,ZYL910的代码也存在类似于GDI+的问题

可以说用系统自带的API无法完美的实现这个,VB中唯一的方式就是自己用双线性插值法编写,这个可以通过改进ZYL910的代码实现。
http://files.cnblogs.com/laviewpbt/plgblt%e6%97%8b%e8%bd%ac.rar

旋转一度的效果应该如下
laviewpbt 2010-05-31
  • 打赏
  • 举报
回复 1
上面参考代码的链接发错了,应该是这个
http://files.cnblogs.com/laviewpbt/zyl910_Rotate.rar
laviewpbt 2010-05-31
  • 打赏
  • 举报
回复
我给的代码不是利用插值做的,而是系统的API函数做,GDI+旋转是倒的和他的坐标系有些关系,这个改成一样的要改哪些坐标的参数。我没空帮你调整的。


要自己用代码实现,可以参考这个代码
http://files.cnblogs.com/laviewpbt/zyl910_Scale.rar

当然,要实现如我上图那样的效果就要对zyl910的代码在进行改进,这个就是我的不共享的秘密了。
lzqgj 2010-05-31
  • 打赏
  • 举报
回复
上面的例子不是插值法实现的吧?用GDI+的效果确实不错,但怎么用GDI+旋转图像是倒转的?怎么处理呢?
lzqgj 2010-05-31
  • 打赏
  • 举报
回复
下面是旋转1、2、3三个角度前后对比的图。看到1、2度与原图差别太大了。

怎么上传不了图片
东方之珠 2010-05-31
  • 打赏
  • 举报
回复
经过测试,不是变形,图象正常,是有锯齿。为何得出结论:基本看不出原来图像的模样了?
Option Explicit
Private Type POINTAPI
x As Long
y As Long
End Type
Private Declare Function PlgBlt Lib "gdi32.dll" (ByVal hdcDest As Long, ByRef 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 Const PI As Double = 3.1415926

Public Function TurnPic(ByVal ObjMe As Object, ByVal pObj1 As Object, ByVal pObj2 As Object, ByVal dThetaDeg As Double)
Dim pt(1 To 3) As POINTAPI, p4 As POINTAPI
Dim dx As Long, dy As Long
Dim I As Long, offsetX As Long, offsetY As Long
Dim Sida As Double
Dim MaxX As Long, MaxY As Long, MinX As Long, MinY As Long

Sida = dThetaDeg * PI / 180

dx = ObjMe.ScaleX(pObj1.Picture.Width, vbHimetric, vbPixels)
dy = ObjMe.ScaleX(pObj1.Picture.Height, vbHimetric, vbPixels)

pt(1).x = dy * Sin(Sida)
pt(1).y = dy - dy * Cos(Sida)
pt(2).x = pt(1).x + dx * Cos(Sida)
pt(2).y = pt(1).y + dx * Sin(Sida)
pt(3).x = 0: pt(3).y = dy

'p4不用在pt()之阵列,它是由pt(1)-pt(3)所推出
p4.x = pt(3).x + dx * Cos(Sida)
p4.y = pt(3).y + dx * Sin(Sida)

I = PlgBlt(pObj2.hDC, pt(1), pObj1.hDC, 0, 0, dx, dy, 0, 0, 0)
pObj2.Refresh
End Function

Private Sub Command1_Click()
TurnPic Me, Picture1, Picture2, 45 '调用旋转处理函数,旋转1度
End Sub

1,486

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧