新手提问:图像处理相关问题~~~

arthasalex 2007-05-13 01:36:45
想要实现的功能是对图像平移、扭转和横竖向拉压变形的分步还原处理,目前三部分功能代码的编写已经基本完成,现在的问题是如何把它们结合起来。想法是在两个picturebox内载入两幅图像,然后对一幅经过上述三种变形的图像先后进行横竖向拉压、扭转和平移处理,直到把两幅图像化为相同。现在的问题是这三步都想在已有图像的基础上进行,即想在已有的picturebox内清除原有图像,然后生成一幅新图像,如此循环,请问各位大大如何实现,最好有详细过程讲解和相类似的示例程序,多谢大家~~~
...全文
309 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
homezj 2007-05-18
  • 打赏
  • 举报
回复
“Picture4是可以隐藏起来的”意思是在界面上放上叫Picture4的picturebox而不用来显示图像是吧?
===============
是的,将其Visible=false

说picture4作为一个中介能多次利用么
=================
可以,每次中转时,在绘入新内容前,若只是绘入正常不透明矩形,直接使用,若有透明或不规则形状需求,需先Cls擦掉旧图。不要用它的Picture属性。

我还是对你说的第一种方法更感兴趣
=================
GDI函数使用可以参见MSDN,示例其中也有,网上可搜到更多,有兴趣就要多找找。哪里不懂可在论坛上多问问。

homezj 2007-05-15
  • 打赏
  • 举报
回复
这个代码我在网上见过。
能看出LZ对GDI了解得不多,这种API与VB结合的用法,使你受限很多,总想着使用Picture对象想复制与保存位图,没这必要。
你可能不明白,Picture对象就是我说的StdPicture,不用picturebox一样可以使用StdPicture。

其实若会用GDI函数,完全可已建DC,自已建Bmp对象,放弃picturebox做中转站。
按LZ的需求,处理后的新位图,不可能直接覆盖原图,必须得有一个中间DC中转过渡后再覆盖。
有两种方案:
1、不用第三个picturebox,就可以自建一个内存DC代替,在这个DC中处理完成后,再清除Picture中的图像,从自己DC中复制新位图过去即可。这些东西,用过很简单,没用过,得先学些相关知识;

2、暂时用Picture4,不过Picture4是可以隐藏起来的(相当于VB帮你建的内存DC了),需让Picture4.AutoRedraw=True。
Set Picture4.Picture = Picture4.Image可不要,
直接复制进Picture2
Set Picture2.Picture = Nothing '先清除原图
复制有两种:
Bitblt Picture2.hdc,0,0,Picture4.ScaleWidth,Picture4.ScaleHeight,Picture4.hdc,0,0,vbSrcCopy
'Picture2.refresh '若没显示,加上这句
picturebox都要用像素做单位


Picture2.PaintPicture Picture4.Image,0,0
arthasalex 2007-05-15
  • 打赏
  • 举报
回复
非常感谢小吉!耐心帮助了我这么多!不过还有一些疑问:
我使用了你说的第二种方法,用的是bitblt语句,关于你说的“Picture4是可以隐藏起来的”意思是在界面上放上叫Picture4的picturebox而不用来显示图像是吧?
还有一个就是这种方法可以重复使用么,就是说picture4作为一个中介能多次利用么,不但这个旋转时用,以后的拉压我也想用可以么?
第三个疑问,我还是对你说的第一种方法更感兴趣,能给我一些思路上的指导么,告诉我应该按什么步骤来做,需要学习些什么函数,我以后可以慢慢来消化。
arthasalex 2007-05-14
  • 打赏
  • 举报
回复
扭转其实就是旋转,那部分代码的算法是在两幅图像上各点取两个点获得坐标值,然后计算斜率,再反求出角度,这样就可以根据两个角度的差值,用PlgBlt实现了。下边是扭转的代码(求角度那段的省略):

Private Sub Rotate(ByRef picDestHdc As Long, xPos As Long, yPos As Long, _
ByVal Angle As Long, _
ByRef picSrcHdc As Long, srcXoffset As Long, srcYoffset As_ Long, ByVal srcWidth As Long, ByVal srcHeight As Long)


Dim Points(3) As POINTS2D
Dim DefPoints(3) As POINTS2D
Dim ThetS As Single, ThetC As Single
Dim ret As Long

Points(0).x = -srcWidth * 0.5
Points(0).y = -srcHeight * 0.5

Points(1).x = Points(0).x + srcWidth
Points(1).y = Points(0).y

Points(2).x = Points(0).x
Points(2).y = Points(0).y + srcHeight

ThetS = Sin(Angle * NotPI) 'NotPI = 3.14159265238 / 180
ThetC = Cos(Angle * NotPI)
DefPoints(0).x = (Points(0).x * ThetC - Points(0).y * ThetS) + xPos
DefPoints(0).y = (Points(0).x * ThetS + Points(0).y * ThetC) + yPos

DefPoints(1).x = (Points(1).x * ThetC - Points(1).y * ThetS) + xPos
DefPoints(1).y = (Points(1).x * ThetS + Points(1).y * ThetC) + yPos

DefPoints(2).x = (Points(2).x * ThetC - Points(2).y * ThetS) + xPos
DefPoints(2).y = (Points(2).x * ThetS + Points(2).y * ThetC) + yPos

PlgBlt picDestHdc, DefPoints(0), picSrcHdc, srcXoffset, srcYoffset, srcWidth, srcHeight, 0, 0, 0

End Sub

Private Sub Command7_Click()
Dim g, h, k As Double
g = Atn((f1 - b1) / (e1 - a1))
h = Atn((f2 - b2) / (e2 - a2)) '(a1,b1),(a2,b2),(e1,f1),(e2,f2)是所点的参考点坐标
k = h - g

Rotate Picture4.hdc, Picture4.ScaleWidth / 2, Picture4.ScaleHeight / 2, -180 * k / PI, Picture2.hdc, 0, 0, picture2.ScaleWidth, Picture2.ScaleHeight 'PI = 3.14159265238
Set Picture4.Picture = Picture4.Image
End Sub

我的程序的处理流程是这样的:打开两幅图像(在两个picturebox内显示)---在两幅图上各点3个参考点---处理拉压---处理旋转---处理平移。
想要的效果是每处理完一种变形,新生成的图像在已有的一个picturebox里显示(原有图像被覆盖),然后处理下一种变形,新生成的图像再在该picturebox里显示,如此循环直到三种变形都处理完。然而这个目前还无法实现,只能借助于第3个picturebox,感觉很麻烦。
homezj 2007-05-14
  • 打赏
  • 举报
回复
把你扭转和平移的代码贴出来,看看,才知道你的目的。

平移能看明白,简单指定x,y用Bitblt就能完成。

扭转是哪类呢?
变形?或是旋转?或是翻转?
前两种PaintPicture做不到,要用PlgBlt
最后一种将宽或高设为负值,可用PaintPicture完成
homezj 2007-05-14
  • 打赏
  • 举报
回复
前面说的很神秘,原来“拉压”处理就是StretchBlt缩放^_^

Set Picture2.Picture=Picture4.Picture
就行了

说实话,若总想着用Picture属性,做图像处理是很麻烦的。若你实在弄不懂GDI函数,可用StdPicture对象,外加PaintPicture方法就可满足你的要求。现在,你用的办法有些“四不象”,资源占用大、麻烦先不说,因Picture传来传去,效率还不如纯VB方法高!
arthasalex 2007-05-14
  • 打赏
  • 举报
回复
因为也是初学VB,想必一定是走了不少弯路,而且所谓的处理都是些最简单的方法。我的程序不仅有拉压处理,还有扭转和平移,所以不知道你所说的StdPicture和PaintPicture能不能用,能给我些例子参考下么?
arthasalex 2007-05-13
  • 打赏
  • 举报
回复
下边是我现在的代码:

'打开图像1
Private Sub Command2_Click()
CommonDialog1.Filter = " Pictures (*.bmp)|*.bmp"
CommonDialog1.ShowOpen
filename = CommonDialog1.filename
If filename <> "" Then
Picture1.Picture = LoadPicture(filename)
End If
End Sub

'打开图像2
Private Sub Command3_Click()
CommonDialog2.Filter = " Pictures (*.bmp)|*.bmp"
CommonDialog2.ShowOpen
filename = CommonDialog2.filename
If filename <> "" Then
Picture2.Picture = LoadPicture(filename)
End If
End Sub

'拉压处理,m和n可以求得,处理后的图像显示在picture4内
Private Sub Command6_Click()
Call StretchBlt(Picture4.hdc, 0, 0, Picture2.ScaleWidth * m, Picture2.ScaleHeight * n, Picture2.hdc, 0, 0, Picture2.ScaleWidth, Picture2.ScaleHeight, vbSrcCopy)
Set Picture4.Picture = Picture4.Image
End Sub

我想要的效果就是把处理后的图像还显示在Picture2里,而这里之前已经载入了一幅图像了
homezj 2007-05-13
  • 打赏
  • 举报
回复
奇了怪了,会处理不会显示?
bitblt绘入就行了。
很想问一句:显示不出来,你又是怎么知道处理得对不对呢?
TechnoFantasy 2007-05-13
  • 打赏
  • 举报
回复
看你要做什么处理了。
arthasalex 2007-05-13
  • 打赏
  • 举报
回复
目的其实就是想把一个picturebox内已有的一幅图像经过某种处理后再在这个picturebox里显示出来,相当于用处理后的图像把原来的图像覆盖掉,这个我不知道要如何实现
homezj 2007-05-13
  • 打赏
  • 举报
回复
没看明白你的目的?最好贴出代码,就具体问题提问!

807

社区成员

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

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