首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

VB 怎么透明PICTUREBOX

2012-08-26 
VB 如何透明PICTUREBOX?我的意思是,当读入或者画上某一些图片在PICTUREBOX里,然后再根据需要的透明颜色做

VB 如何透明PICTUREBOX?
我的意思是,当读入或者画上某一些图片在PICTUREBOX里,然后再根据需要的透明颜色做背景透明,有没有相关的API呢,最好是不要太占资源等?请发给我,谢谢!

[解决办法]
了解一下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。
[解决办法]
实现半透明是可以的。http://www.qqgb.com/Program/VB/VBSource/Program_52816.html
[解决办法]
可以使用透明复制API,可以指定需要透明的颜色,API声明如下:

VB code
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
[解决办法]
'这是使一个Shape1和一个Picture1透明的代码
VB code
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As LongPrivate Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As LongPrivate Declare Function SetLayeredWindowAttributes Lib "user32" (ByVal hwnd As Long, ByVal crKey As Long, ByVal bAlpha As Byte, ByVal dwFlags As Long) As LongConst WS_EX_LAYERED = &H80000Const GWL_EXSTYLE = (-20)Const LWA_COLORKEY = &H1Dim 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_COLORKEYEnd Sub 


[解决办法]

探讨
还有就是不要使用PictureBox,直接在窗口上绘图。如果真实镂空图片框,那只能使用SetWindowRgn,AlphaBlend是实现不了的。

[解决办法]
以下代码是将一个picturebox控件根据绘出的图形裁剪成异形的例子。但如果图片不是用程序绘制出的,就很麻烦了,因为这种情况下很难生成一个区域对象。
VB code
Option ExplicitPrivate Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As LongPrivate Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As LongPrivate Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As LongPrivate Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As LongPrivate Const RGN_AND = 1Private Const RGN_COPY = 5Private Const RGN_OR = 2Private Const RGN_XOR = 3Private 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 LongPrivate 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 LongPrivate Declare Function CreatePen Lib "gdi32" (ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As LongPrivate Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As LongPrivate 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 SubPrivate Sub Form_Load()    With Picture1        .ScaleMode = vbPixels        .FillStyle = 0        .FillColor = vbRed        .AutoRedraw = True    End WithEnd Sub
[解决办法]
目前我也只学到取每点像素的办法,使用函数SetWindowRgn 设置异形,没有发现更好的办法,不过速度还能接受。
如果你需要比较代码,可查阅:http://blog.csdn.net/mfkinfo/archive/2009/02/16/3894494.aspx

热点排行