Results 1 to 18 of 18

Thread: Help : RGB -> Black and White

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Oct 2002
    Posts
    31

    Smile Help : RGB -> Black and White

    Hi,
    I'm looking for a simple code to put an Image (Colored one) into Black and White...

    Any links or sample codes ?

  2. #2
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    The easiest way to do it is to simply extract the individual RGB values from the color, average them, and create a new color using the average for all three components. Simple, but it is incorrect, visually, as far as I know. Someone else may be in here at some point to give you a better solution.

    Z.

  3. #3
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    Do this:
    VB Code:
    1. Function GetLum(R As Long, G As Long, B As Long) As Long
    2. Dim Hi As Long
    3. Dim Lo As Long
    4.  
    5.     Hi = Max(R, G, B)
    6.     Lo = Min(R, G, B)  
    7.     GetLum = (Hi + Lo) / 2
    8.  
    9. End Function
    10. Function Min(R As Long, G As Long, B As Long) As Long
    11.     If R < G Then
    12.         If R < B Then
    13.             Min = R
    14.         Else
    15.             Min = B
    16.         End If
    17.     Else
    18.         If G < B Then
    19.             Min = G
    20.         Else
    21.             Min = B
    22.         End If
    23.     End If
    24. End Function
    25. Function Max(R As Long, G As Long, B As Long) As Long
    26.     If R > G Then
    27.         If R > B Then
    28.             Max = R
    29.         Else
    30.             Max = B
    31.         End If
    32.     Else
    33.         If G > B Then
    34.             Max = G
    35.         Else
    36.             Max = B
    37.         End If
    38.     End If
    39. End Function
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  4. #4

    Thread Starter
    Junior Member
    Join Date
    Oct 2002
    Posts
    31

    Hum...

    Here is what i have done, i think it's more smart...
    Attached Files Attached Files

  5. #5
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    In the graphics biz, the standard way is to calculate the luminance value for each point and then map it over to an array of
    RGB(0,0,0) -> RGB(255,255,255).

    I've posted this code about four-five times now - do a search on
    this forum for the word 'luminance' Don't search on my name - my account got hosed and the search engine thinks my old posts belong to 'Guest' or something.

  6. #6
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    It's a weighted average. Using the weighting factors
    R: 0.3333 (1/3)
    G: 0.59
    B: 011

    So the grey value would be
    (0.3333 * R + 0.59 * G + 0.11 * B) / 3
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  7. #7
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    try mine:

    VB Code:
    1. Public Sub BlackAndWhite(ByVal picPictureBox As PictureBox)
    2. Dim X As Single
    3. Dim Y As Single
    4. Dim PrevColor As Long
    5. Dim NewColor As Long
    6. Dim TempColor As Single
    7.  
    8. For Y = 0 To picPictureBox.ScaleHeight - 1
    9.     For X = 0 To picPictureBox.ScaleWidth - 1
    10.         PrevColor = GetPixel(picPictureBox.hdc, X, Y)
    11.         TempColor = Round2((GetRed(PrevColor) + GetGreen(PrevColor) + GetBlue(PrevColor)) / 3)
    12.         NewColor = RGB(TempColor, TempColor, TempColor)
    13.         SetPixelV picPictureBox.hdc, X, Y, NewColor
    14.     Next X
    15. Next Y
    16.  
    17. End Sub
    18.  
    19. Public Function GetRed(Color As Long) As Integer
    20. GetRed = Color And 255
    21. End Function
    22.  
    23. Public Function GetGreen(Color As Long) As Integer
    24. GetGreen = (Color And 65280) \ 256
    25. End Function
    26.  
    27. Public Function GetBlue(Color As Long) As Integer
    28. GetBlue = (Color And 16711680) \ 65535
    29. End Function
    30.  
    31. Public Function Round2(Number As Single) As Integer
    32. If Number - Round(Number) >= 0.05 Then Number = Round(Number, 1) + 0.1
    33. If Number - Round(Number) < 0.05 Then Number = Round(Number, 1)
    34. Round2 = Number
    35. End Function
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  8. #8
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    here's a sample image changed with my code:

    Attached Images Attached Images  
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  9. #9
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Originally posted by cyborg
    try mine:

    VB Code:
    1. Public Sub BlackAndWhite(ByVal picPictureBox As PictureBox)
    2. Dim X As Single
    3. Dim Y As Single
    4. Dim PrevColor As Long
    5. Dim NewColor As Long
    6. Dim TempColor As Single
    7.  
    8. For Y = 0 To picPictureBox.ScaleHeight - 1
    9.     For X = 0 To picPictureBox.ScaleWidth - 1
    10.         PrevColor = GetPixel(picPictureBox.hdc, X, Y)
    11.         TempColor = Round2((GetRed(PrevColor) + GetGreen(PrevColor) + GetBlue(PrevColor)) / 3)
    12.         NewColor = RGB(TempColor, TempColor, TempColor)
    13.         SetPixelV picPictureBox.hdc, X, Y, NewColor
    14.     Next X
    15. Next Y
    16.  
    17. End Sub
    18.  
    19. Public Function GetRed(Color As Long) As Integer
    20. GetRed = Color And 255
    21. End Function
    22.  
    23. Public Function GetGreen(Color As Long) As Integer
    24. GetGreen = (Color And 65280) \ 256
    25. End Function
    26.  
    27. Public Function GetBlue(Color As Long) As Integer
    28. GetBlue = (Color And 16711680) \ 65535
    29. End Function
    30.  
    31. Public Function Round2(Number As Single) As Integer
    32. If Number - Round(Number) >= 0.05 Then Number = Round(Number, 1) + 0.1
    33. If Number - Round(Number) < 0.05 Then Number = Round(Number, 1)
    34. Round2 = Number
    35. End Function
    Perhaps this was the first post?

    Z.

  10. #10
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    you mean your post?
    i just showed a routine i made to make it easy for him...
    the other 2 ones didnt work properly...
    the first one took the average from the lowest and highest value from r, g and b.....
    the other one changed to less colors...
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  11. #11

    Thread Starter
    Junior Member
    Join Date
    Oct 2002
    Posts
    31

    Lightbulb Ok guys...

    Just look closely at the name of the function : Black & White, it means NO GREY. (2 Colors : 1. White, 2. Black )

    I've build this little Module on the principles that :
    (Recall)

    RGB(0,0,0) = BLACK

    RGB(255,255,255) = WHITE

    So a colour is coded on 3 Bytes stored in a long (4 Bytes)
    R G B R G B
    a Colour is coded to &H 00 00 00 to & H FF FF FF

    I extract each colors (R, G, B) by an AND and see if each of them are bigger than 127 (Brithness indeed, no ?)


    Your code is great, and helpfull, thanks !


    But what do you think about writing a function like :

    GreyImage(pPictureBox as PictureBox, byval GreyLevel as byte)

    Where GreyLevel is the accuracy in grey :
    Example :
    (Grey level cannot be 0 or 1), because
    GreyLevel =2, it will be black and white only
    GreyLevel =3 will be black and white and Perfect Grey

    and so on... with different grey levels

  12. #12

    Thread Starter
    Junior Member
    Join Date
    Oct 2002
    Posts
    31

    Help on SAVE Picture afterwards

    Once the picture is modified, if i want to save to disk, it doesn't work using the SavePicture function

    Should i call a API function and give it hDC of the picture box ??

  13. #13
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    For the GrayLevel function:
    pseudocode
    VB Code:
    1. Dim px As Pixel
    2. Dim clr As Color
    3. Dim gr As Byte
    4. Dim i As Integer
    5. If GrayLevel < 2 Then
    6.   Exit Sub
    7. End If
    8. For px = Each Pixel in pPictureBox
    9.   clr = px.color
    10.   gr = (0.3333*clr.red+0.59*clr.green+0.11*clr.blue)/3
    11.   ' You need to refine this part, it doesn't work this way
    12.   For i = 1 To GrayLevel-1
    13.     If gr < (255 / GrayLevel)*i Then
    14.       gr = (255/GrayLevel)*i-1
    15.       Goto Done
    16.     End If
    17.   Next i
    18.   gr = 255
    19. Done:
    20.   clr.red = clr.green = clr.blue = gr
    21.   px.color = clr
    22. Next px

    The problem of this spacing algorithm is that every one that I could come up when thinking about this would either not work with more than 2 greys or exactly black & white.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  14. #14

    Thread Starter
    Junior Member
    Join Date
    Oct 2002
    Posts
    31
    Thanks
    But, I haven't understand your post on :

    It's a weighted average. Using the weighting factors
    R: 0.3333 (1/3)
    G: 0.59
    B: 011

    So the grey value would be
    (0.3333 * R + 0.59 * G + 0.11 * B) / 3

    Can you develop why is there coefficient in front of R,G,B
    I thought grey was RGB(127,127,127) .....
    Thanks.

  15. #15
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    There are many shades of gray, computers usually display 256 (RGB(0,0,0) to RGB(255,255,255)).
    When you have a color picture you usually take the average of the color components to get the shade of grey this particular color correspondends to. But it would be wrong to simply use every color component the same (0.3333*r+0.3333*g+0.3333*b), because the human eye values the components differently. A bright green looks far brighter than a bright blue. Therefore you have to use a weighted average: (0.3333*r+0.59*g+0.11*b). I have to correct myself, there is no /3 there.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  16. #16

    Thread Starter
    Junior Member
    Join Date
    Oct 2002
    Posts
    31

    Thanks a lot

    I didn't know that, is there any article on the subject ?

  17. #17
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    There probably is, but I don't know where...

    Try googling for "grayscale conversion" or similar terms.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  18. #18
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    If you want a black-and-white artistic feeling, use one of the excellent grayscale code snippets in this thread, and if R, G, and B are under 128, make all 0 (black). If they're 128 or over, make them 255 (white).

    If you want something more accurate, you'll have to look into things like dithering and error defusion.
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width