Android Question Convert image to black and white

angel_

Well-Known Member
Licensed User
Longtime User
I use the following code from @klaus to convert an image to black and white but some definition is missing around the edges of the image to black, is there any way to improve it?


B4X:
Public Sub BlackAndWhite (Image As B4XBitmap, Threshold As Int) As B4XBitmap
    Private x, y, Mean, BWCol As Int
    Private col0, col1 As ARGBColor
    Private bmcImage, bmcResult As BitmapCreator
  
    bmcImage.Initialize(Image.Width, Image.Height)
    bmcImage.CopyPixelsFromBitmap(Image)
    bmcResult.Initialize(Image.Width, Image.Height)
  
    For y = 0 To Image.Height -1
        For x = 0 To Image.Width -1
            bmcImage.GetARGB(x, y, col0)
'            col1.a = col0.a
            Mean = (col0.r + col0.g + col0.b) / 3
            If Mean > Threshold Then
                BWCol = 255
            Else
                BWCol = 0
            End If
            col1.a = 255
            col1.r = BWCol
            col1.g = BWCol
            col1.b = BWCol
            bmcResult.SetARGB(x, y, col1)
        Next
    Next
    Return bmcResult.Bitmap
End Sub
 

Attachments

  • Project.zip
    16.9 KB · Views: 206

klaus

Expert
Licensed User
Longtime User
I tested your project on my Samsung Galaxy S10.
It does not look that bad.
My be it is the anti-aliasing, but this cannot be removed.

1637438863543.png
 
Upvote 0

angel_

Well-Known Member
Licensed User
Longtime User
It is a loss of definition at the edges of the lines, they appear slightly pixelated, it is also slightly noticeable when there are texts
 

Attachments

  • Screenshot_20211121-110517.jpg
    Screenshot_20211121-110517.jpg
    5 KB · Views: 204
  • Screenshot_20211121-110455.jpg
    Screenshot_20211121-110455.jpg
    6.1 KB · Views: 199
Upvote 0

klaus

Expert
Licensed User
Longtime User
I think that the original images have anti-aliasing.
Then, part of the lighter pixels are converted to black and the others to white depending on the threshold.
Can you check if, the lighter pixels, the alpha value is lower than 255.
If yes, try eventually to keep the original alpha value by commenting col1.a = 255.
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
It is a loss of definition at the edges of the lines, they appear slightly pixelated, it is also slightly noticeable when there are texts
Does your use-case allow grayscale?

Also, I have a vague recollection that in analog television the HSV <==> RGB conversion weights green more heavily than red and blue.

Perhaps in digital television too, if the video compression is anything like JPEG where similar conversions occur.
 
Last edited:
Upvote 0

klaus

Expert
Licensed User
Longtime User
I played a bit more with your problem.
I saw that you have modified the original conversion routine.
I tried with the original routine and I get a gray background, and was surprised why, even with alpha = 0.
I noticed that you use and B4XImageView.
I tried to replace it by an ImageView, which gives better results.
Set the background color to white and use the original routine.
 
Upvote 0

Johan Schoeman

Expert
Licensed User
Longtime User
Upvote 0

angel_

Well-Known Member
Licensed User
Longtime User
I have used a mix of @klaus code and Erel grayscale (from B4XBitmapEffects) and it works great:

B4X:
BlackAndWhite(pnl.Snapshot, 200)

B4X:
Public Sub BlackAndWhite (Image As B4XBitmap, Threshold As Int) As B4XBitmap
    Private x, y, Mean, BWCol As Int
    Private col0, col1 As ARGBColor
    Private bmcImage, bmcResult As BitmapCreator
  
    bmcImage.Initialize(Image.Width, Image.Height)
    bmcImage.CopyPixelsFromBitmap(Image)
    bmcResult.Initialize(Image.Width, Image.Height)
  
    For y = 0 To Image.Height -1
        For x = 0 To Image.Width -1
            bmcImage.GetARGB(x, y, col0)
            Mean = (col0.r + col0.g + col0.b) / 3
            If Mean > Threshold Then
                BWCol = 255
            Else If Mean > 0.75 * Threshold Then
                BWCol = col0.r * 0.21 + col0.g * 0.72 + 0.07 * col0.b
            Else
                BWCol = 0
            End If
            col1.r = BWCol
            col1.g = BWCol
            col1.b = BWCol
            col1.a = 255
            bmcResult.SetARGB(x, y, col1)
        Next
    Next
    Return bmcResult.Bitmap
End Sub
 
Upvote 0
Top