views:

106

answers:

2

Duplicate of http://stackoverflow.com/questions/885696/how-do-i-perform-a-better-colorize-function

I am using this function in vb2005 to colorize a pixel, however when a user chooses a color >50 i begin to lose detail in the image, any idea how i can fix this?

Private badcolor As Color = Color.FromArgb(0, 0, 0, 0)
  Public Function grayscalePixel(ByVal basecolor As Color) As Color

        Return grayscalePixel(basecolor, 0.3, 0.59, 0.11)

    End Function

    Public Function grayscalePixel(ByVal basecolor As Color, ByVal RedMix As Double, ByVal GreenMix As Double, ByVal BlueMix As Double) As Color
        If basecolor.A = 0 Then
            Return badcolor
        End If
        If (RedMix + GreenMix + BlueMix > 1) Or (RedMix + GreenMix + BlueMix <= 0) Then
            Return grayscalePixel(basecolor)
        End If

        Dim grayval As Integer = basecolor.R * RedMix + basecolor.G * GreenMix + basecolor.B * BlueMix

        Return Color.FromArgb(basecolor.A, grayval, grayval, grayval)
    End Function
    Public Function colorizePixel(ByVal basecolor As Color, ByVal colorize As Color) As Color
        If basecolor.A = 0 Then
            Return badcolor
        End If
        Dim grayval As Color = grayscalePixel(basecolor)

        Dim r As Integer = Convert.ToInt32(grayval.R) + Convert.ToInt32(colorize.R)
        Dim g As Integer = Convert.ToInt32(grayval.R) + Convert.ToInt32(colorize.G)
        Dim b As Integer = Convert.ToInt32(grayval.R) + Convert.ToInt32(colorize.B)

        If r > 255 Then
            r = 255
        End If
        If g > 255 Then
            g = 255
        End If
        If b > 255 Then
            b = 255
        End If
        If r < 0 Then
            r = 0
        End If
        If g < 0 Then
            g = 0
        End If
        If b < 0 Then
            b = 0
        End If

        Return Color.FromArgb(basecolor.A, r, g, b)
    End Function
A: 

Well, I'm mainly a C# guy, but a good formula is something like this:

rNew = (grayVal.R / 2) + (colorize.R / 2)

Or if you prefer floating-point arithmatec:

rNew = (0.5F * grayval.R) + (0.5F * colorize.R)

The second one is a general overlay function set to a 50/50 blend. You can change the constants in order to get a different ratio. Note that if Option Explicit is on, you must cast grayval.R and colorize.R to floats!

MiffTheFox
A: 

i think it should be like:

float avg = 
           (float)
           (
              0.2225 * basecolor.R + 
              0.7169 * basecolor.G + 
              0.606 * basecolor.B
           ) / 765.0f;
return Color.fromARGB
       (
          basecolor.A, 
          avg * colorize.R, 
          avg * colorize.G, 
          avg * colorize.B
       );

EDIT :

this one, my formula, it works..

private Color colorizeme(Color basecolor, Color colorize)
{
    Color c =  Color.FromArgb
               (
                  (int)(0.2225 * basecolor.R),
                  (int)(0.7169 * basecolor.G),
                  (int)(0.606 * basecolor.B)
               );
    return Color.FromArgb
           (
              basecolor.A,
              (c.R * 63 + colorize.R * 192) >> 8,
              (c.G * 192 + colorize.G * 63) >> 8,
              (c.B * 155 + colorize.B * 100) >> 8
           );
}

EDIT : VB.Net version

Private Function colorizeme(ByVal basecolor As Color, ByVal colorize As Color) As Color
    Dim c As Color = Color.FromArgb(CInt((0.2225 * basecolor.R)), CInt((0.7169 * basecolor.G)), CInt((0.606 * basecolor.B)))
    Return Color.FromArgb(basecolor.A, (c.R * 63 + colorize.R * 192) >> 8, (c.G * 192 + colorize.G * 63) >> 8, (c.B * 155 + colorize.B * 100) >> 8)
End Function
Tolgahan Albayrak
Im sorry since i can only read vb, what language is the ">>" in?
Jim
sorry, i added the vb.net version
Tolgahan Albayrak