将函数从c#2008转换为Vb6.0错误

时间:2014-03-28 21:14:48

标签: c# vb6

我需要你帮助将代码转换为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);
}

3 个答案:

答案 0 :(得分:1)

您的代码存在两个主要问题:

  • 数组边界 - 在VB6中,声明数组时括号中的数字是顶部边界,而不是元素数。默认情况下,下边界将为01,具体取决于Option Base设置。始终提供下限和上限都是一种好习惯。
  • 图片大小 - 您正在使用不应该使用的图片框ScaleWidth 首先,它是控件的宽度,可能不等于所包含图像的宽度 其次,ScaleWidth属性取决于父ScaleMode,而您希望它始终以像素为单位给出结果。因此,您应该使用bmp.ScaleX(bmp.Image.Width, vbHimetric, vbPixels)代替,这将始终以正确的单位给出正确的宽度。

另外,我敢打赌你没有为你的照片框设置AutoRedrawTrue - 你必须,否则下面的代码什么都不做。

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之间的区别,因为它可能会在不同的元素上执行计算,并且比你预期的更早或者晚退出循环。