Click here to Skip to main content
15,896,118 members
Home / Discussions / .NET (Core and Framework)
   

.NET (Core and Framework)

 
AnswerRe: Data Conversions Pin
Abhinav S9-Jun-13 16:33
Abhinav S9-Jun-13 16:33 
AnswerRe: Data Conversions Pin
Richard MacCutchan9-Jun-13 21:12
mveRichard MacCutchan9-Jun-13 21:12 
GeneralRe: Data Conversions Pin
Richard Deeming10-Jun-13 1:39
mveRichard Deeming10-Jun-13 1:39 
GeneralRe: Data Conversions Pin
Richard MacCutchan10-Jun-13 1:44
mveRichard MacCutchan10-Jun-13 1:44 
AnswerRe: Data Conversions Pin
Richard Deeming10-Jun-13 1:40
mveRichard Deeming10-Jun-13 1:40 
GeneralRe: Data Conversions Pin
Bram van Kampen11-Jun-13 13:11
Bram van Kampen11-Jun-13 13:11 
AnswerRe: Data Conversions Pin
Ron Beyer10-Jun-13 3:07
professionalRon Beyer10-Jun-13 3:07 
QuestionExecution time difference between VB.Net and C# code Pin
TnTinMn9-Jun-13 11:36
TnTinMn9-Jun-13 11:36 
A few weeks ago there I seen a question regarding converting colors to grayscale equivalents and it caught my interest. I found an article that presented various methods and decided to give it a try in VB.Net. This is my code.
<System.Runtime.CompilerServices.Extension()> _
Public Function ToGrayScale(ByVal img As Image, ByVal method As Methods) As Image
   If Not [Enum].IsDefined(GetType(Methods), method) Then
      Return Nothing
   End If

   ' set the grayscale function to use for conversion
   Dim gsfunc As Func(Of Color, Color) = Nothing
   Select Case method
      Case Methods.Average : gsfunc = AddressOf Average
      Case Methods.CorrectingForTheHumanEye_Gimp : gsfunc = AddressOf Gimp
      Case Methods.CorrectingForTheHumanEye_BT_601 : gsfunc = AddressOf BT_601
      Case Methods.CorrectingForTheHumanEye_BT_709 : gsfunc = AddressOf BT_709
      Case Methods.Desaturation : gsfunc = AddressOf Desaturation
      Case Methods.DecompositionMax : gsfunc = AddressOf DecompositionMax
      Case Methods.DecompositionMin : gsfunc = AddressOf DecompositionMin
      Case Methods.SingleColorRed : gsfunc = AddressOf SingleColorRed
      Case Methods.SingleColorGreen : gsfunc = AddressOf SingleColorGreen
      Case Methods.SingleColorBlue : gsfunc = AddressOf SingleColorBlue
   End Select

   ' create a 32bppArgb bitmap from source image
   Dim bm As New Bitmap(img.Width, img.Height, Imaging.PixelFormat.Format32bppArgb)
   Dim g As Graphics = Graphics.FromImage(bm)
   g.DrawImageUnscaled(img, Point.Empty)
   g.Dispose()

   Dim bmdata As System.Drawing.Imaging.BitmapData

   ' convert 1 row of pixels at a time
   Dim pixelcolors(0 To bm.Width - 1) As Int32
   For row As Int32 = 0 To bm.Height - 1

      ' lock the row in memory
      bmdata = bm.LockBits(New Rectangle(0, row, bm.Width, 1), _
                           Drawing.Imaging.ImageLockMode.ReadWrite, _
                           bm.PixelFormat)

      ' get row data as array integer color
      System.Runtime.InteropServices.Marshal.Copy(bmdata.Scan0, pixelcolors, 0, bm.Width)

      ' convert each pixel color to grayscale using selected method
      For col As Int32 = 0 To bm.Width - 1
         pixelcolors(col) = gsfunc(Color.FromArgb(pixelcolors(col))).ToArgb()
      Next col

      System.Runtime.InteropServices.Marshal.Copy(pixelcolors, 0, bmdata.Scan0, bm.Width)

      bm.UnlockBits(bmdata) ' release memory lock
      bmdata = Nothing

   Next row

   Return bm

End Function

Everything seems to work fine, but I have been trying various tweaks to improve the processing speed and wondered if converting it to C# and using a pointer approach would help. I initially translated my exiting VB code to C# to make sure I had this part correct before modifying the logic to use pointers.
public static Image ToGrayScale(this Image img, Methods method)
{
    if (!(Enum.IsDefined(typeof(Methods), method)))
    {
        return null;
    }

    // set the grayscale function to use for conversion
    Func<Color, Color> gsfunc = null;
    switch (method)
    {
        case Methods.Average:
            gsfunc = Average;
            break;
        case Methods.CorrectingForTheHumanEye_Gimp:
            gsfunc = Gimp;
            break;
        case Methods.CorrectingForTheHumanEye_BT_601:
            gsfunc = BT_601;
            break;
        case Methods.CorrectingForTheHumanEye_BT_709:
            gsfunc = BT_709;
            break;
        case Methods.Desaturation:
            gsfunc = Desaturation;
            break;
        case Methods.DecompositionMax:
            gsfunc = DecompositionMax;
            break;
        case Methods.DecompositionMin:
            gsfunc = DecompositionMin;
            break;
        case Methods.SingleColorRed:
            gsfunc = SingleColorRed;
            break;
        case Methods.SingleColorGreen:
            gsfunc = SingleColorGreen;
            break;
        case Methods.SingleColorBlue:
            gsfunc = SingleColorBlue;
            break;
    }

    // create a 32bppArgb bitmap from source image
    Bitmap bm = new Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
    Graphics g = Graphics.FromImage(bm);
    g.DrawImageUnscaled(img, Point.Empty);
    g.Dispose();

    System.Drawing.Imaging.BitmapData bmdata = null;

    // convert 1 row of pixels at a time
    Int32[] pixelcolors = new Int32[bm.Width];
    for (Int32 row = 0; row < bm.Height; row++)
    {

        // lock the row in memory
        bmdata = bm.LockBits(new Rectangle(0, row, bm.Width, 1), System.Drawing.Imaging.ImageLockMode.ReadWrite, bm.PixelFormat);

        // get row data as array integer color
        System.Runtime.InteropServices.Marshal.Copy(bmdata.Scan0, pixelcolors, 0, bm.Width);

        // convert each pixel color to grayscale using selected method
        for (Int32 col = 0; col < bm.Width; col++)
        {
            pixelcolors[col] = gsfunc(Color.FromArgb(pixelcolors[col])).ToArgb();
        }

        System.Runtime.InteropServices.Marshal.Copy(pixelcolors, 0, bmdata.Scan0, bm.Width);

        bm.UnlockBits(bmdata); // release memory lock
        bmdata = null;

    }

    return bm;

}

However, the C# version takes approximately 50% longer to execute than the VB version and this is what I do not understand and was hoping someone could provide an explanation for this performance difference. I freely admit that I only dabble in C#, so maybe there is something inherent to C# that makes this logic fine in VB and not in C#? To rule out a FUBAR'ed install, I have moved the code to another computer and got the same results (assuming it is not messed up too).

For testing purposes, I have using this grayscale method.
VB
Private Function BT_601(ByVal c As Color) As Color
   Dim gs As Int32 = CInt((c.R * 0.299) + (c.G * 0.587) + (c.B * 0.114))
   Return Color.FromArgb(c.A, gs, gs, gs)
End Function

C#
private static Color BT_601(Color c)
{
    Int32 gs = Convert.ToInt32((c.R * 0.299) + (c.G * 0.587) + (c.B * 0.114));
    return Color.FromArgb(c.A, gs, gs, gs);
}

I have uploaded the project (http://sdrv.ms/13qH5OM[^]) if anyone wants to look at it. This was developed under VS2008.

Thanks in advance for insights on this.
AnswerRe: Execution time difference between VB.Net and C# code Pin
Bram van Kampen9-Jun-13 14:37
Bram van Kampen9-Jun-13 14:37 
GeneralRe: Execution time difference between VB.Net and C# code Pin
TnTinMn9-Jun-13 16:00
TnTinMn9-Jun-13 16:00 
AnswerRe: Execution time difference between VB.Net and C# code Pin
Ron Beyer9-Jun-13 19:05
professionalRon Beyer9-Jun-13 19:05 
GeneralRe: Execution time difference between VB.Net and C# code Pin
TnTinMn10-Jun-13 3:59
TnTinMn10-Jun-13 3:59 
QuestionDisplay Comments in winforms Pin
Member 100156599-Jun-13 5:04
Member 100156599-Jun-13 5:04 
AnswerRe: Display Comments in winforms Pin
Abhinav S9-Jun-13 5:23
Abhinav S9-Jun-13 5:23 
QuestionHow The data by jquery Pin
hansraj.sm5-Jun-13 20:52
hansraj.sm5-Jun-13 20:52 
AnswerRe: How The data by jquery Pin
Richard MacCutchan5-Jun-13 21:15
mveRichard MacCutchan5-Jun-13 21:15 
AnswerRe: How The data by jquery Pin
Abhinav S5-Jun-13 22:14
Abhinav S5-Jun-13 22:14 
AnswerRe: How The data by jquery Pin
Pete O'Hanlon5-Jun-13 22:20
mvePete O'Hanlon5-Jun-13 22:20 
QuestionHow to defeat God Pin
Bram van Kampen5-Jun-13 15:02
Bram van Kampen5-Jun-13 15:02 
AnswerRe: How to defeat God Pin
Dave Kreskowiak5-Jun-13 15:13
mveDave Kreskowiak5-Jun-13 15:13 
AnswerRe: How to defeat God Pin
Pete O'Hanlon5-Jun-13 19:23
mvePete O'Hanlon5-Jun-13 19:23 
AnswerRe: How to defeat God Pin
Richard MacCutchan5-Jun-13 21:14
mveRichard MacCutchan5-Jun-13 21:14 
GeneralRe: How to defeat God Pin
Bram van Kampen7-Jun-13 0:25
Bram van Kampen7-Jun-13 0:25 
GeneralRe: How to defeat God Pin
Richard MacCutchan7-Jun-13 1:02
mveRichard MacCutchan7-Jun-13 1:02 
AnswerRe: How to defeat God Pin
dusty_dex6-Jun-13 6:59
dusty_dex6-Jun-13 6:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.