在很多的UI设计上,透明处理作为一个又炫又实用的方法受到很多人的喜爱,就像曾经VB6.0版本的图片框不支持Alpha通道直接导致不支持透明效果让很多地方不得不用底色相同来模仿透明效果,实在是让人头疼,在.NET里让图片框可以支持透明不得不说一件让人高兴的事.
但是光支持Alpha通道也不能解决所有事情,比如说让这个图片框动态调节透明度就不行了(是不是太矫情了,微软明明提供了GDI+这么强大的东西……),下面就介绍一下在VB.NET中可以是图片框透明的两种方法(两种方法的原理都是利用GDI+使图片透明,然后放到背景色为透明色的图片框中实现的)
第一种方法:利用Bitmap.LockBits方法配合Marshal.Copy方法将图片转为一维数组,操作一维数组比操作二维数组要快得多,并且少了SetPixel和GetPixel,效率提高不是一丁点,下面的方法将写在PictureBox的Paint事件里
BitmapTemp = New Bitmap(Bitmaps.Width, Bitmaps.Height) '创建一个新 BITMAP,用来进行编辑
BitmapTemp = Bitmaps.Clone 'Bitmaps是源图像,制作一个浅表副本赋值给另一个Bitmap用来操作
Dim data As BitmapData '声明一个位图属性对象
data = BitmapTemp.LockBits(New Rectangle(0, 0, Bitmaps.Width, Bitmaps.Height), ImageLockMode.ReadWrite, Imaging.PixelFormat.Format32bppArgb) '在内存中锁定图片,并转换成非托管数据(可编辑的一维数组)
Dim bytes As Integer = data.Width * data.Height * 4 '计算图片长度(乘4是因为一个像素有4个字节的信息 ARGB)
Dim rgbValues(bytes - 1) As Byte
Dim ptr As IntPtr = data.Scan0 '获得图像的第一位地址
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes) '复制流到 二进制数组
For i = 0 To bytes - 1 Step 4
If rgbValues(i + 3) <> 0 Then 'i+3是因为这个一维数组每4个元素为一个像素,排列方式为BGRA,第四位是Alpha通道信息
If OPacitys < 0 Then
OPacitys = 0
ElseIf OPacitys > 255 Then
OPacitys = 255
End If
(i + 3) = OPacity '设置透明度(此处的OPacity是外面设置的一个属性,最大为255最小为0 因为是一个字节)
End If
Next
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, data.Scan0, rgbValues.Length) '将非托管内存重新分配到托管区域,组成图片原来的二维数组
BitmapTemp.UnlockBits(data) '解锁
e.Graphics.DrawImage(BitmapTemp, 0, 0, Bitmaps.Width, Bitmaps.Height) '绘到 控件上
使用这种方法亲测可以使图片框做到透明(其实就vb.net教程是图片透明了),不过效率一般,并且最好使用带有Alpha通道的图片,也就是PNG,不过其他图片也是可以的,因为在LockBits时已经强制转成4个字节的图片信息了