Public Function FastBlur(Optional ByVal Radius As Long = 3) As Boolean
Dim x As Long, y As Long
Dim Rad As Long, Circumference As Long
Dim SumRowRed As Long, SumRowGreen As Long
Dim SumRowBlue As Long, mPtrC As Long
Dim Width As Long, Height As Long
Dim DataArr(0 To 2) As Byte, pDataArr(0 To 0) As Long
Dim OldArrPtr As Long, OldpArrPtr As Long
Dim DataArrC(0 To 2) As Byte, pDataArrC(0 To 0) As Long
Dim OldArrPtrC As Long, OldpArrPtrC As Long
Dim Left As Long, Right As Long
Dim Top As Long, Bottom As Long
Dim TempT As Long, TempB As Long
If mHdc <> 0 Or mBmpInfo.biBitCount = 32 Then
If Radius < 1 Then Radius = 1
If Radius > 500 Then Radius = 500 '修正参数范围
Width = Me.Width: Height = Me.Height
Rad = Radius
Circumference = Rad * 2 + 1
For x = 1 To Width - 1 '计算第一行像素除(0,0)点外其他像素的模糊值
Left = x - Rad - 1 '水平方向循环起始处
Right = x + Rad '水平方向循环终止处
SumRed(x) = SumRed(x - 1) '先复制前一个像素点相关信息
SumGreen(x) = SumGreen(x - 1) '
SumBlue(x) = SumBlue(x - 1)
SumNum(x) = SumNum(x - 1)
For y = 0 To Rad '我们可以明确知道第一行像素在垂直方向上的领域只需从0开始
If y < Height Then '防止在rad>Height的时候出错
If Left >= 0 Then '是有效的像素
pDataArrC(0) = mPtrC + mWidthBytes * y + Left * 4 '寻址
SumRed(x) = SumRed(x) - DataArrC(2) '对第一行的其他像素,模糊值等于前一个像素的模糊值减去模糊区域最左侧还要左一个单位的总和然后加上最右侧区域的那列的模糊值
SumGreen(x) = SumGreen(x) - DataArrC(1)
SumBlue(x) = SumBlue(x) - DataArrC(0)
SumNum(x) = SumNum(x) - 1 '计数器也要加1
End If
If Right < Width Then
pDataArrC(0) = mPtrC + mWidthBytes * y + Right * 4 '加上最右侧那一列的像素(如果存在的话)
SumRed(x) = SumRed(x) + DataArrC(2)
SumGreen(x) = SumGreen(x) + DataArrC(1)
SumBlue(x) = SumBlue(x) + DataArrC(0)
SumNum(x) = SumNum(x) + 1 '计数器也要加1
End If
End If
Next
pDataArr(0) = mPtr + x * 4 '计算要修改处的地址
DataArr(2) = SumRed(x) \ SumNum(x)
DataArr(1) = SumGreen(x) \ SumNum(x)
DataArr(0) = SumBlue(x) \ SumNum(x)
Next '至此,第一行像素的模糊值计算完毕
'*********************************************第二阶段结束*******************************************
For y = 1 To Height - 1 '从第二行开始算起了
Top = y - Rad - 1
Bottom = y + Rad
SumRowRed = 0
SumRowGreen = 0
SumRowBlue = 0
TempT = mPtrC + mWidthBytes * Top '为了加快计算速度
TempB = mPtrC + mWidthBytes * Bottom
For x = 0 To Rad '计算每行的第一个像素的模糊值
If x < Width Then '在合理的范围内
If Top >= 0 Then '减去不在该像素领域的一行像素累加和
pDataArrC(0) = TempT + x * 4
SumRowRed = SumRowRed - DataArrC(2) '等于上一行的像素模糊值减去最上行还上一行的像素值加上最下部的像素和
SumRowGreen = SumRowGreen - DataArrC(1)
SumRowBlue = SumRowBlue - DataArrC(0)
SumNum(0) = SumNum(0) - 1
End If
If Bottom < Height Then '加上新增像素的一行像素累加和
pDataArrC(0) = TempB + x * 4
SumRowRed = SumRowRed + DataArrC(2)
SumRowGreen = SumRowGreen + DataArrC(1)
SumRowBlue = SumRowBlue + DataArrC(0)
SumNum(0) = SumNum(0) + 1
End If
End If
Next
SumRed(0) = SumRed(0) + SumRowRed
SumGreen(0) = SumGreen(0) + SumRowGreen
SumBlue(0) = SumBlue(0) + SumRowBlue
pDataArr(0) = mPtr + mWidthBytes * y '更新该点
DataArr(2) = SumRed(0) \ SumNum(0)
DataArr(1) = SumGreen(0) \ SumNum(0)
DataArr(0) = SumBlue(0) \ SumNum(0)
For x = 1 To Width - 1 '计算一行的其他像素
Left = x - Rad - 1
If Left >= 0 Then
If Top >= 0 Then
pDataArrC(0) = TempT + Left * 4 '加上新增领域的一列像素累加和
SumRowRed = SumRowRed + DataArrC(2)
SumRowGreen = SumRowGreen + DataArrC(1)
SumRowBlue = SumRowBlue + DataArrC(0)
End If
If Bottom < Height Then
pDataArrC(0) = TempB + Left * 4 '减去不在该像素领域一列像素累加和
SumRowRed = SumRowRed - DataArrC(2)
SumRowGreen = SumRowGreen - DataArrC(1)
SumRowBlue = SumRowBlue - DataArrC(0)
End If
End If
If Top < 0 Then
If x >= Radius And x < Width - Radius Then
SumNum(x) = SumNum(x) + Circumference '移入一行像素数
ElseIf x < Radius Then
SumNum(x) = SumNum(x) + Radius + x + 1
Else
SumNum(x) = SumNum(x) + Radius + (Width - x)
End If
End If
If Bottom >= Height Then
If x >= Radius And x < Width - Radius Then
SumNum(x) = SumNum(x) - Circumference
ElseIf x < Radius Then
SumNum(x) = SumNum(x) - (Radius + x + 1) '移出一行像素
Else
SumNum(x) = SumNum(x) - (Radius + (Width - x))
End If
End If
Right = x + Rad
If Right < Width Then
If Top >= 0 Then
pDataArrC(0) = TempT + Right * 4 '同样的道理
SumRowRed = SumRowRed - DataArrC(2)
SumRowGreen = SumRowGreen - DataArrC(1)
SumRowBlue = SumRowBlue - DataArrC(0)
End If
If Bottom < Height Then
pDataArrC(0) = TempB + Right * 4
SumRowRed = SumRowRed + DataArrC(2)
SumRowGreen = SumRowGreen + DataArrC(1)
SumRowBlue = SumRowBlue + DataArrC(0)
End If
End If