我需要你帮助将代码转换为Visual Basic 6.0,我转换了Visual C#2008中的所有代码,但是,生成的图片不是真正的彩色图像,图像应该比之前更亮。
VB 6.0代码:
Public Sub White(bmp As PictureBox)
Dim levelR(256) As Double
Dim levelG(256) As Double
Dim levelB(256) As Double
Dim color As Pixel
'claculates levels
For y = 0 To bmp.ScaleHeight - 1
For x = 0 To bmp.ScaleWidth - 1
color = LongToPix(GetPixel(bmp.hdc, x, y))
levelR(color.Red) = levelR(color.Red) + 1
levelG(color.Green) = levelG(color.Green) + 1
levelB(color.Blue) = levelB(color.Blue) + 1
Next x
Next y
'calculates probibality
Dim pixelsCount As Double
Dim pR_level(256) As Double
Dim pG_level(256) As Double
Dim pB_level(256) As Double
pixelsCount = bmp.ScaleWidth * bmp.ScaleHeight
For I = 0 To 256
pR_level(I) = levelR(I) / pixelsCount
pG_level(I) = levelG(I) / pixelsCount
pB_level(I) = levelB(I) / pixelsCount
Next I
'compute cumulative probabilities
Dim pR_total(256) As Double
Dim pG_total(256) As Double
Dim pB_total(256) As Double
pR_total(0) = pR_level(0)
pG_total(0) = pG_level(0)
pB_total(0) = pB_level(0)
'compute reference black and white levels
For m = 1 To 256
pR_total(m) = pR_total(m - 1) + pR_level(m)
pG_total(m) = pG_total(m - 1) + pG_level(m)
pB_total(m) = pB_total(m - 1) + pB_level(m)
Next m
Dim K As Integer
Dim refBR As Integer
Dim refWR As Integer
Dim refBG As Integer
Dim refWG As Integer
Dim refBB As Integer
Dim refWB As Integer
refBR = -1
refWR = -1
refBG = -1
refWG = -1
refBB = -1
refWB = -1
For K = 0 To 256
If refBR = -1 And pR_total(K) > 0.05 Then
refBR = K
End If
If refWR = -1 And pR_total(K) > 0.95 Then
refWR = K
End If
If refBG = -1 And pG_total(K) > 0.05 Then
refBG = K
End If
If refWG = -1 And pG_total(K) > 0.95 Then
refWG = K
End If
If refBB = -1 And pB_total(K) > 0.05 Then
refBB = K
End If
If refWB = -1 And pB_total(K) > 0.95 Then
refWB = K
End If
Next K
'calculation level stretching table
Dim gR(256) As Byte
Dim gG(256) As Byte
Dim gB(256) As Byte
Dim J As Integer
For J = 0 To 256
gR(J) = transformLevel(J, refBR, refWR)
gG(J) = transformLevel(J, refBG, refWG)
gB(J) = transformLevel(J, refBB, refWB)
Next J
'transform components of source pixels according to the stretching table
For y = 0 To bmp.ScaleHeight - 1
For x = 0 To bmp.ScaleWidth - 1
color = LongToPix(GetPixel(bmp.hdc, x, y))
'SetPixel Form1.WhitePic.hdc, x, y, RGB(gR(color.Red), gG(color.Green), gB(color.Blue))
Form1.WhitePic.PSet (x, y), RGB(gR(color.Red), gG(color.Green), gB(color.Blue))
Next x
Next y
End Sub
Private Function transformLevel(f As Integer, refB As Integer, refW As Integer) As Byte
If f <= refB Then
transformLevel = 0
Exit Function
End If
'// Math.Log(refW) will produce 0 in denominator if refW <= 1, so check
If f >= refW Or refW <= 1 Then
transformLevel = 255
Exit Function
End If
If refB > 0 Then lnRefB = Log(refB) Else G = (Log(f) - lnRefB) / (Log(refW) - lnRefB)
transformLevel = 255 * G
Exit Function
End Function
我转换的C#代码是:
public static Bitmap White(Bitmap sourceBitmap)
{
var bitmap = new Bitmap(sourceBitmap);
// Step2: calculate levels
int[] levelR = new int[256];
int[] levelG = new int[256];
int[] levelB = new int[256];
for (int y = 0; y < bitmap.Height; ++y)
{
for (int x = 0; x < bitmap.Width; ++x)
{
Color c = bitmap.GetPixel(x, y);
++levelR[c.R];
++levelG[c.G];
++levelB[c.B];
}
}
// Step3: calculate probabilities
int pixelsCount = bitmap.Width * bitmap.Height;
double[] pR_level = new double[256];
double[] pG_level = new double[256];
double[] pB_level = new double[256];
for (int i = 0; i < 256; ++i)
{
pR_level[i] = levelR[i] / (double)pixelsCount;
pG_level[i] = levelG[i] / (double)pixelsCount;
pB_level[i] = levelB[i] / (double)pixelsCount;
}
// Step4: compute cumulative probabilities
double[] pR_total = new double[256];
double[] pG_total = new double[256];
double[] pB_total = new double[256];
pR_total[0] = pR_level[0];
pG_total[0] = pG_level[0];
pB_total[0] = pB_level[0];
for (int i = 1; i < 256; ++i)
{
pR_total[i] = pR_total[i - 1] + pR_level[i];
pG_total[i] = pG_total[i - 1] + pG_level[i];
pB_total[i] = pB_total[i - 1] + pB_level[i];
}
// Step5: compute reference black and white levels
int refBR = -1;
int refWR = -1;
int refBG = -1;
int refWG = -1;
int refBB = -1;
int refWB = -1;
for (int i = 0; i < 256; ++i)
{
if (refBR == -1 && pR_total[i] > 0.05)
refBR = i;
if (refWR == -1 && pR_total[i] > 0.95)
refWR = i;
if (refBG == -1 && pG_total[i] > 0.05)
refBG = i;
if (refWG == -1 && pG_total[i] > 0.95)
refWG = i;
if (refBB == -1 && pB_total[i] > 0.05)
refBB = i;
if (refWB == -1 && pB_total[i] > 0.95)
refWB = i;
}
// Step6.1: calculation level stretching table
byte[] gR = new byte[256];
byte[] gG = new byte[256];
byte[] gB = new byte[256];
for (int i = 0; i < 256; ++i)
{
gR[i] = transformLevel(i, refBR, refWR);
gG[i] = transformLevel(i, refBG, refWG);
gB[i] = transformLevel(i, refBB, refWB);
}
// Step6.2: transform components of source pixels according to the stretching table
for (int y = 0; y < bitmap.Height; ++y)
{
for (int x = 0; x < bitmap.Width; ++x)
{
Color c = bitmap.GetPixel(x, y);
bitmap.SetPixel(x, y, Color.FromArgb(gR[c.R], gG[c.G], gB[c.B]));
}
}
return bitmap;
}
private static byte transformLevel(int f, int refB, int refW)
{
if (f <= refB)
return 0;
// Math.Log(refW) will produce 0 in denominator if refW <= 1, so check
if (f >= refW || refW <= 1)
return 255;
double lnRefB = refB > 0 ? Math.Log(refB) : 0;
double g = (Math.Log(f) - lnRefB) / (Math.Log(refW) - lnRefB);
return (Byte)(255 * g);
}
答案 0 :(得分:1)
您的代码存在两个主要问题:
0
或1
,具体取决于Option Base
设置。始终提供下限和上限都是一种好习惯。ScaleWidth
首先,它是控件的宽度,可能不等于所包含图像的宽度
其次,ScaleWidth
属性取决于父ScaleMode
,而您希望它始终以像素为单位给出结果。因此,您应该使用bmp.ScaleX(bmp.Image.Width, vbHimetric, vbPixels)
代替,这将始终以正确的单位给出正确的宽度。另外,我敢打赌你没有为你的照片框设置AutoRedraw
到True
- 你必须,否则下面的代码什么都不做。
Private Declare Function GetPixel Lib "gdi32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function SetPixel Lib "gdi32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long
Private Type ColorRefComponents
Red As Byte
Green As Byte
Blue As Byte
Alpha As Byte
End Type
Private Type ColorRefSolid
Color As Long
End Type
Public Sub White(ByVal bmp As PictureBox)
Dim levelR(0 To 255) As Double
Dim levelG(0 To 255) As Double
Dim levelB(0 To 255) As Double
Dim Color As ColorRefComponents
Dim ColorSolid As ColorRefSolid
Dim WidthInPixels As Long
Dim HeightInPixels As Long
WidthInPixels = bmp.ScaleX(bmp.Image.Width, vbHimetric, vbPixels)
HeightInPixels = bmp.ScaleY(bmp.Image.Height, vbHimetric, vbPixels)
'claculates levels
Dim x As Long, y As Long
For y = 0 To HeightInPixels - 1
For x = 0 To WidthInPixels - 1
ColorSolid.Color = GetPixel(bmp.hdc, x, y)
LSet Color = ColorSolid
levelR(Color.Red) = levelR(Color.Red) + 1
levelG(Color.Green) = levelG(Color.Green) + 1
levelB(Color.Blue) = levelB(Color.Blue) + 1
Next
Next
'calculates probibality
Dim pixelsCount As Double
Dim pR_level(0 To 255) As Double
Dim pG_level(0 To 255) As Double
Dim pB_level(0 To 255) As Double
pixelsCount = WidthInPixels * HeightInPixels
Dim i As Long
For i = 0 To 255
pR_level(i) = levelR(i) / pixelsCount
pG_level(i) = levelG(i) / pixelsCount
pB_level(i) = levelB(i) / pixelsCount
Next
'compute cumulative probabilities
Dim pR_total(0 To 255) As Double
Dim pG_total(0 To 255) As Double
Dim pB_total(0 To 255) As Double
pR_total(0) = pR_level(0)
pG_total(0) = pG_level(0)
pB_total(0) = pB_level(0)
'compute reference black and white levels
For i = 1 To 255
pR_total(i) = pR_total(i - 1) + pR_level(i)
pG_total(i) = pG_total(i - 1) + pG_level(i)
pB_total(i) = pB_total(i - 1) + pB_level(i)
Next
Dim refBR As Long
Dim refWR As Long
Dim refBG As Long
Dim refWG As Long
Dim refBB As Long
Dim refWB As Long
refBR = -1
refWR = -1
refBG = -1
refWG = -1
refBB = -1
refWB = -1
For i = 0 To 255
If refBR = -1 And pR_total(i) > 0.05 Then refBR = i
If refWR = -1 And pR_total(i) > 0.95 Then refWR = i
If refBG = -1 And pG_total(i) > 0.05 Then refBG = i
If refWG = -1 And pG_total(i) > 0.95 Then refWG = i
If refBB = -1 And pB_total(i) > 0.05 Then refBB = i
If refWB = -1 And pB_total(i) > 0.95 Then refWB = i
Next
'calculation level stretching table
Dim gR(0 To 255) As Byte
Dim gG(0 To 255) As Byte
Dim gB(0 To 255) As Byte
For i = 0 To 255
gR(i) = transformLevel(i, refBR, refWR)
gG(i) = transformLevel(i, refBG, refWG)
gB(i) = transformLevel(i, refBB, refWB)
Next
'transform components of source pixels according to the stretching table
For y = 0 To HeightInPixels - 1
For x = 0 To WidthInPixels - 1
ColorSolid.Color = GetPixel(bmp.hdc, x, y)
LSet Color = ColorSolid
Color.Red = gR(Color.Red)
Color.Green = gG(Color.Green)
Color.Blue = gB(Color.Blue)
LSet ColorSolid = Color
SetPixel bmp.hdc, x, y, ColorSolid.Color
Next
Next
bmp.Refresh
End Sub
Private Function transformLevel(ByVal f As Long, ByVal refB As Long, ByVal refW As Long) As Byte
Select Case True
Case f <= refB
transformLevel = 0
Case f >= refW Or refW <= 1
transformLevel = 255
Case Else
'Math.Log(refW) will produce 0 in denominator if refW <= 1, so check
Dim lnRefB As Double
If refB > 0 Then lnRefB = Log(refB) Else lnRefB = 0
Dim G As Double
G = (Log(f) - lnRefB) / (Log(refW) - lnRefB)
transformLevel = 255 * G
End Select
End Function
答案 1 :(得分:0)
我不能说它是否是答案(没有VB来测试)
但是C#:for(int i = 1; i&lt; 256; ++ i)
在VB中:对于i = 1到255
在你的代码中(对于m和For K),你最多可以达到256
答案 2 :(得分:0)
我现在有点模糊,但有一些重要的事情需要注意:
在C#和VB6中声明数组是不同的。以下代码将生成相同的数组:
C#
int[] numbers = new int[5];
VB6
Dim numbers(4) As Integer
您是VB6程序员还是C#程序员?
注意循环中C#中y ++和++ y之间的区别,因为它可能会在不同的元素上执行计算,并且比你预期的更早或者晚退出循环。