VB 如何透明PICTUREBOX?

penguinhzf 2009-04-15 04:30:29
我的意思是,当读入或者画上某一些图片在PICTUREBOX里,然后再根据需要的透明颜色做背景透明,有没有相关的API呢,最好是不要太占资源等?请发给我,谢谢!
...全文
1659 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
jessezappy 2012-08-13
  • 打赏
  • 举报
回复
我做了例子,参见:http://blog.csdn.net/jessezappy/article/details/7862178
mfkinfo 2009-04-19
  • 打赏
  • 举报
回复
目前我也只学到取每点像素的办法,使用函数SetWindowRgn 设置异形,没有发现更好的办法,不过速度还能接受。
如果你需要比较代码,可查阅:http://blog.csdn.net/mfkinfo/archive/2009/02/16/3894494.aspx
penguinhzf 2009-04-18
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 lyserver 的回复:]
使用SetWindowRgn吧,它可以满足你的要求。
[/Quote]
有相关的例子吗?能给我看看吗?
VBToy 2009-04-18
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 lyserver 的回复:]
还有就是不要使用PictureBox,直接在窗口上绘图。如果真实镂空图片框,那只能使用SetWindowRgn,AlphaBlend是实现不了的。
[/Quote]
赞同。还有一种方法就是用自义控件,设置maskpicture和maskcolor,就是弯子绕大了……
熊孩子开学喽 2009-04-18
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 penguinhzf 的回复:]
大家是否误会了我的意思,我的意思是假设我有一个PICTUREBOX,画了3个图形,颜色包括红色,蓝色和绿色,现在我希望是在这些图形以外的图片框的其他部分,设置成透明,能看到窗口的背景图片,该怎么设置?

我已有一个例子,但该例子是通过两个循环语句来获取每一点的颜色,这样如果图片框较大是非常缓慢的,能有一些好的例子吗?谢谢各位!
[/Quote]

不知道你这个例子实际是怎么弄的,我猜可能是把PICTURE上需要显示出来的部分画到窗体上?

如果你只是想在窗体上显示出来这个效果,那么用TRANPARENTBLT这个API,就可以把PICTURE控件上的图片指定一个透明颜色,贴到窗体上去. 因为只用一个API调用,比逐像素画要快N百倍.
但是这样的后贵就是,PICTRUE控件不出现在窗体的可见范围内(或直接是不可见),也因此无法响应用户事件.

lyserver 2009-04-18
  • 打赏
  • 举报
回复
代码楼上的朋友已给出。
如果嫌CombineRgn效率低,还可以使用PathToRegion,只不过绘图时需要使用GDI函数,而不能直接使用VB本身的绘图命令。
VBToy 2009-04-18
  • 打赏
  • 举报
回复
以下代码是将一个picturebox控件根据绘出的图形裁剪成异形的例子。但如果图片不是用程序绘制出的,就很麻烦了,因为这种情况下很难生成一个区域对象。
Option Explicit
Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
Private Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long
Private Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Const RGN_AND = 1
Private Const RGN_COPY = 5
Private Const RGN_OR = 2
Private Const RGN_XOR = 3
Private Declare Function Rectangle Lib "gdi32" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function Ellipse Lib "gdi32" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function CreatePen Lib "gdi32" (ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long

Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Sub Command1_Click()
Dim h As Long
Dim hRect As Long, hCl As Long, hC As Long
h = Picture1.hWnd
Picture1.Line (100, 100)-Step(80, 150), vbBlue, BF '画一个蓝色的长方形

'Rectangle h, 100, 100, 180, 250
hRect = CreateRectRgn(100, 100, 180, 250) ' 生成这个区域对象
Picture1.Circle (120, 130), 80, vbRed '画一个圆形
Picture1.FillColor = vbRed
'Ellipse h, 40, 50, 200, 210
hCl = CreateEllipticRgn(40, 50, 200, 210)
hC = CombineRgn(hRect, hRect, hCl, RGN_OR)
If hC <> 0 Then
SetWindowRgn h, hRect, True
End If
DeleteObject hCl
DeleteObject hRect

End Sub

Private Sub Form_Load()
With Picture1
.ScaleMode = vbPixels
.FillStyle = 0
.FillColor = vbRed
.AutoRedraw = True
End With
End Sub
lyserver 2009-04-17
  • 打赏
  • 举报
回复
还有就是不要使用PictureBox,直接在窗口上绘图。如果真实镂空图片框,那只能使用SetWindowRgn,AlphaBlend是实现不了的。
lyserver 2009-04-17
  • 打赏
  • 举报
回复
使用SetWindowRgn吧,它可以满足你的要求。
penguinhzf 2009-04-17
  • 打赏
  • 举报
回复
大家是否误会了我的意思,我的意思是假设我有一个PICTUREBOX,画了3个图形,颜色包括红色,蓝色和绿色,现在我希望是在这些图形以外的图片框的其他部分,设置成透明,能看到窗口的背景图片,该怎么设置?

我已有一个例子,但该例子是通过两个循环语句来获取每一点的颜色,这样如果图片框较大是非常缓慢的,能有一些好的例子吗?谢谢各位!
舉杯邀明月 2009-04-16
  • 打赏
  • 举报
回复
Up~~~~~~~~~~
tlt6668 2009-04-16
  • 打赏
  • 举报
回复
rgb(0,0,0)
SYSSZ 2009-04-16
  • 打赏
  • 举报
回复
'这是使一个Shape1和一个Picture1透明的代码
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function SetLayeredWindowAttributes Lib "user32" (ByVal hwnd As Long, ByVal crKey As Long, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long
Const WS_EX_LAYERED = &H80000
Const GWL_EXSTYLE = (-20)
Const LWA_COLORKEY = &H1

Dim rtn&

Private Sub Form_Load()
Picture1.BackColor = RGB(66, 66, 66)
Shape1.BackColor = RGB(66, 66, 66)
rtn = GetWindowLong(hwnd, GWL_EXSTYLE)
rtn = rtn Or WS_EX_LAYERED
SetWindowLong hwnd, GWL_EXSTYLE, rtn
SetLayeredWindowAttributes hwnd, RGB(66, 66, 66), &H2, LWA_COLORKEY
End Sub


lyserver 2009-04-16
  • 打赏
  • 举报
回复
可以使用透明复制API,可以指定需要透明的颜色,API声明如下:

Private Declare Function TransparentBlt Lib "msimg32.dll" _
(ByVal hdcDest As Long, _
ByVal nXOriginDest As Long, _
ByVal nYOriginDest As Long, _
ByVal nWidthDest As Long, _
ByVal nHeightDest As Long, _
ByVal hdcSrc As Long, _
ByVal nXOriginSrc As Long, _
ByVal nYOriginSrc As Long, _
ByVal nWidthSrc As Long, _
ByVal nHeightSrc As Long, _
ByVal crTransparent As Long _
) As Long

penguinhzf 2009-04-16
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 SupermanKing 的回复:]
了解一下GDI,然后自己写个函数处理吧,通常简单的方法不实用,实用的方法不简单。
我在这方面处理上通常会自己用VC写函数给VB调用,单靠系统的API,很多东西不见得能实现的。
当然,就你的需求来说,有 AlphaBlend 函数可以使用。
从标准的Win32 API 函数来说,用 BitBlt 也可以实现,但需要演码图的支持。给你看个范例:
VB用Bitblt实现透明位图显示

至于 AlphaBlend 函数,说明如下:

函数功能:该函数用来显示…
[/Quote]

谢谢!等我试一下先.
东方之珠 2009-04-15
  • 打赏
  • 举报
回复
实现半透明是可以的。http://www.qqgb.com/Program/VB/VBSource/Program_52816.html
现在还是人类 2009-04-15
  • 打赏
  • 举报
回复
了解一下GDI,然后自己写个函数处理吧,通常简单的方法不实用,实用的方法不简单。
我在这方面处理上通常会自己用VC写函数给VB调用,单靠系统的API,很多东西不见得能实现的。
当然,就你的需求来说,有 AlphaBlend 函数可以使用。
从标准的Win32 API 函数来说,用 BitBlt 也可以实现,但需要演码图的支持。给你看个范例:
VB用Bitblt实现透明位图显示

至于 AlphaBlend 函数,说明如下:

函数功能:该函数用来显示透明或半透明像素的位图。
函数声明:
Private Declare Function AlphaBlend Lib "msimg32.dll" (ByVal hdc As Long, ByVal nXoriginDest As Long, _
ByVal nYOriginDest As Long, ByVal nWidthDest As Long, _
ByVal nHeghtdest As Long, ByVal hdcSrc As Long, _
ByVal nXOriginSrc As Long, ByVal nYOriginSrc As Long, _
ByVal nWidthSrc As Long, ByVal nHeightSrc As Long, _
ByVal blendFunction As BLENDFUNCT) As Long


hdc Long,指向目标设备环境的句柄。
nXoriginDest Long,指定目标矩形区域左上角的X轴坐标,按逻辑单位。
nYOriginDest Long,指定目标矩形区域左上角的Y轴坐标,按逻辑单位。
nWidthDest Long,指定目标矩形区域的宽度,按逻辑单位。
nHeghtdest Long,指向目标矩形区域高度的句柄,按逻辑单位。
hdcSrc Long,指向源设备环境的句柄。
nXOriginSrc Long,指定源矩形区域左上角的X轴坐标,按逻辑单位。
nYOriginSrc Long,指定源矩形区域左上角的Y轴坐标,按逻辑单位。
nWidthSrc Long,指定源矩形区域的宽度,按逻辑单位。
nHeightSrc Long,指定源矩形区域的高度,按逻辑单位。
blendFunction BLENDFUNCTION结构,指定用于源位图和目标位图使用的alpha混合功能,用于整个源位图的全局alpha值和格式信息。源和目标混
合功能当前只限为AC_SRC_OVER。

BLENDFUNCTION 结构声明:
Private Type BLENDFUNCTION
BlendOp As Byte '指明了源混合操作,但只支持AC_SRC_OVER,即根据源alpha值把源图像叠加到目标图像上。OpenGL的alpha
'混合还支持其他的方式,如常量颜色源。
BlendFlags As Byte '必须是0,也是为以后的应用保留的。
SourceConstantAlpha As Byte
AlphaFormat As Byte '有两个选择:0表示常量alpha值,AC_SRC_ALPHA表示每个像素有各自的alpha通道。
End Type

如果AlphaFormat字段为0,源位图中的所有像素使用同样的常量alpha值,即SourceConstantAlpha字段中的值,该值实际上是0和255,而不是0和1。这里0表示完全透明,255表示完全不透明。目标像素以255-SourceConstantAlpha值作为alpha值。
  如果AlphaFormat字段的值是AC_SRC_ALPHA,源设备表面的每个像素必须有各自的alpha通道。即,必须是32-bpp的物理设备上下文,或是选中了32-bpp DDB和DIB段的内存设备上下文。这些情况下,每个源像素有4个8位通道:红、绿、蓝和alpha。每个像素的alpha通道和SourceConstantAlpha字段一起用于把源和目标混合起来。实际用于计算的运算式如下:
  Tmp.Red = Src.Red * SourceConstantAlpha / 255;
  Tmp.Green = Src.Green * SourceConstantAlpha / 255;
  Tmp.Blue = Src.Blue * SourceConstantAlpha / 255;
  Tmp.Alpha = Src.Alpha * SourceConstantAlpha / 255;
  Beta = 255 – Tmp.alpha;
  Dst.Red = Tmp.Red + Round((Beta * Dst.Red )/255);
  Dst.Green = Tmp.Green + Round((Beta * Dst.Green)/255);
  Dst.Blue = Tmp.Blue + Round((Beta * Dst.Blue )/255);
  Dst.Alpha = Tmp.Alpha + Round((Beta * Dst.Alpha)/255);
  返回值:如果函数执行成功,那么返回值为TRUE;如果函数执行失败,那么返回值为FALSE。

1,485

社区成员

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

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