Question

I have 2 colors coming from an old VB6 format.

In this case, these 2 colors are vbBlack and vbBlack. I need to blend / mix them.

In VB6 said I simply said:

Public Function BlendColors(ByVal lColor1 As Long, ByVal lColor2 As Long) As Long
    BlendColors = RGB( _
        ((lColor1 And &HFF) + (lColor2 And &HFF)) / 2, _
        (((lColor1 \ &H100) And &HFF) + ((lColor2 \ &H100) And &HFF)) / 2, _
        (((lColor1 \ &H10000) And &HFF) + ((lColor2 \ &H10000) And &HFF)) / 2)
End Function

Now with VB.NET, I first have to convert these two Win32 color codes to Color.

I am using

Public Function IntegerToColor(ByVal uColorValue As Integer) As Color
    Dim nColor As Color = ColorTranslator.FromWin32(uColorValue)
    Return nColor
End Function

Then I am using the following function to actually blend these Colors:

Dim nBlendedColor As Color = Color.FromArgb((c1.A + c2.A) \ 2,
                                            (c1.R + c2.R) \ 2,
                                            (c1.G + c2.G) \ 2,
                                            (c1.B + c2.B) \ 2)

This function however throws an OverflowException telling me I may not divide by 0.

What am I doing wrong?

Was it helpful?

Solution

You got an OverflowException "Arithmetic operation resulted in an overflow.". The problem is that the A, R, G, B values are bytes and those can only have values between 0 and 255. Adding two of them might exceed this range. Therefore convert them to integers before adding them.

Public Function BlendColors(ByVal c1 As Color, ByVal c2 As Color) As Color
    Return Color.FromArgb((CInt(c1.A) + CInt(c2.A)) \ 2, _
        (CInt(c1.R) + CInt(c2.R)) \ 2, _
        (CInt(c1.G) + CInt(c2.G)) \ 2, _
        (CInt(c1.B) + CInt(c2.B)) \ 2)
End Function

Note: If you have the Strict option set to On, which is a good thing, VB will not do all conversions automatically as did VB6. Why is this good? Because you know what you are doing. Otherwise the compiler would introduce conversions you are not aware of and which might be unexpected or even harmful. VB still does widening conversions when it is known that a larger type is appropriate. For instance, you could simplify the above calculation by converting only one of the terms: CInt(c1.R) + c2.R. In this case c2.R will automatically be converted to Integer to make it match the type of CInt(c1.R).

OTHER TIPS

Using your exact same BlendColors function, can't you do like this:

Dim winColor1 As Integer = &HA000
Dim winColor2 As Integer = &HB000

Dim blendedWinColor as Integer = BlendColors(winColor1, winColor2)
Dim BlendedColor as Color = ColorTranslator.FromWin32(blendedWinColor)

Cheers

c1.A, c1.B, c1.G etc are BYTES so the adition can overflow. Change c1.A to CInt(c1.A) and the others accordingly.

valter

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top