PhotoShop的自动色阶功能的实现
2009-06-01 15:25:04 来源:WEB开发网以上的SetPicData和GetPicData分别为图像数据显示和读取函数,这里的.biBitCount = 32选择为32位虽然加大了内存的占用量,但是确在一定程度上方便了编程,因为Windows下的位图对象是要求扫描行对齐的,也就是说一行像素的占用字节数必须是4的倍数,之所以这样,我想是因为32位的Windows系统处理4个字节的速度最快吧。
窗体中有三个按钮一个图片框,图片框中请在设计的时候加载一副图像及设置相关参数。
窗体代码:
Option Explicit
Private m_Width As Long '打开的图像的宽度
Private m_Height As Long '打开的图像的高度
Private Sub Form_Load()
m_Width = Pic.ScaleWidth
m_Height = Pic.ScaleHeight
End Sub
Private Sub CmdOpen_Click()
CommonDialog.FileName = ""
CommonDialog.Filter = "All Suppported Images |*.bmp;*.jpg;*.gif;|BMP Images|*.bmp|JPG Images|*.jpg|Gif Images|*.gif"
CommonDialog.ShowOpen
If CommonDialog.FileName <> "" Then
Pic.Picture = LoadPicture(CommonDialog.FileName)
m_Width = Pic.ScaleWidth
m_Height = Pic.ScaleHeight
End If
End Sub
Private Sub CmdDib_Click()
Dim T As Long
Dim PicData() As RGBQUAD
Dim i As Long, j As Long
Dim HistRed(255) As Long, HistGreen(255) As Long
Dim HistBlue(255) As Long
Dim DiffRed As Long, DiffGreen As Long
Dim DiffBlue As Long, Diff As Long
Dim SpeedRed(255) As Byte, SpeedGreen(255) As Byte
Dim SpeedBlue(255) As Byte, Speed(255) As Byte
Dim Sum As Long, Integral As Long
Dim Min As Long, Max As Long
Dim NewMin As Long, NewMax As Long
T = GetTickCount
GetPicData Pic, PicData
For i = 0 To m_Width - 1
For j = 0 To m_Height - 1
HistRed(PicData(i, j).Red) = HistRed(PicData(i, j).Red) + 1
HistGreen(PicData(i, j).Green) = HistGreen(PicData(i, j).Green) + 1
HistBlue(PicData(i, j).Blue) = HistBlue(PicData(i, j).Blue) + 1
Next
Next
For i = 0 To 255
If HistRed(i) <> 0 Then
Min = i
Exit For
End If
Next
For i = 255 To 0 Step -1
If HistRed(i) <> 0 Then
Max = i
Exit For
End If
Next
Sum = 0
For i = Min To Max
Sum = Sum + HistRed(i)
Next
Integral = 0
For i = Min To Max
Integral = Integral + HistRed(i)
If Integral >= Sum * 0.005 Then
NewMin = i
Exit For
End If
Next
For i = NewMin + 1 To Max
Integral = Integral + HistRed(i)
If Integral > Sum * 0.995 Then
NewMax = i
Exit For
End If
Next
For i = 0 To 255
If i <= NewMin Then
SpeedRed(i) = 0
ElseIf i >= NewMax Then
SpeedRed(i) = 255
Else
SpeedRed(i) = (i - NewMin) / (NewMax - NewMin) * 255
End If
Next
''''''''''''''''''''''''''''
For i = 0 To 255
If HistGreen(i) <> 0 Then
Min = i
Exit For
End If
Next
For i = 255 To 0 Step -1
If HistGreen(i) <> 0 Then
Max = i
Exit For
End If
Next
Sum = 0
For i = Min To Max
Sum = Sum + HistGreen(i)
Next
Integral = 0
For i = Min To Max
Integral = Integral + HistGreen(i)
If Integral >= Sum * 0.005 Then
NewMin = i
Exit For
End If
Next
For i = NewMin + 1 To Max
Integral = Integral + HistGreen(i)
If Integral > Sum * 0.995 Then
NewMax = i
Exit For
End If
Next
For i = 0 To 255
If i <= NewMin Then
SpeedGreen(i) = 0
ElseIf i > NewMax Then
SpeedGreen(i) = 255
Else
SpeedGreen(i) = (i - NewMin) / (NewMax - NewMin) * 255
End If
Next
'''''''''''''''''''''''''
For i = 0 To 255
If HistBlue(i) <> 0 Then
Min = i
Exit For
End If
Next
For i = 255 To 0 Step -1
If HistBlue(i) <> 0 Then
Max = i
Exit For
End If
Next
Sum = 0
For i = Min To Max
Sum = Sum + HistBlue(i)
Next
Integral = 0
For i = Min To Max
Integral = Integral + HistBlue(i)
If Integral >= Sum * 0.005 Then
NewMin = i
Exit For
End If
Next
For i = NewMin + 1 To Max
Integral = Integral + HistBlue(i)
If Integral > Sum * 0.995 Then
NewMax = i
Exit For
End If
Next
For i = 0 To 255
If i <= NewMin Then
SpeedBlue(i) = 0
ElseIf i > NewMax Then
SpeedBlue(i) = 255
Else
SpeedBlue(i) = (i - NewMin) / (NewMax - NewMin) * 255
End If
Next
For i = 0 To m_Width - 1
For j = 0 To m_Height - 1
PicData(i, j).Red = SpeedRed(PicData(i, j).Red)
PicData(i, j).Green = SpeedGreen(PicData(i, j).Green)
PicData(i, j).Blue = SpeedBlue(PicData(i, j).Blue)
Next
Next
SetPicData Pic, PicData
Me.Caption = "DIB方法用时" & GetTickCount - T & "毫秒"
End Sub
更多精彩
赞助商链接