Android Code Snippet [B4X] [BitmapCreator] Change Color of Bitmap

Discussion in 'Code Snippets' started by Alexander Stolte, Jul 26, 2018.

  1. Alexander Stolte

    Alexander Stolte Well-Known Member Licensed User

    Hello,

    the Output is not optimal. Have a look down, to Erels code snip for better results.

    With this snip, you can easy change a Bitmap/Icon Color. This only makes sense if the picture is monochrome with a transparent background like Icons.

    Usage:
    Code:
    ImageView1.Bitmap = ChangeImageColor(ImageView1.Bitmap,Colors.Green)
    Function:
    Code:
    Sub ChangeImageColor(icon As B4XBitmap,clr As Int) As B4XBitmap
        
    Dim bc As BitmapCreator
     
        bc.Initialize(icon.Width,icon.Height)
        bc.CopyPixelsFromBitmap(icon)
     
    For y = 0 To bc.mHeight -1
        
    For x = 0 To bc.mWidth -1
         
            
    If bc.IsTransparent(x,y) = False Then
             
                    bc.SetColor(x,y,clr)
                     
            
    End If
         
        
    Next
     
    Next
     
    Return bc.Bitmap

    End Sub
    Example:
    Screenshot_20180726-194018__01.jpg
    Right Original and Left the changed Version.
    The Output is not optimal, maybe you know to make it better, then i will update.
     
    Last edited: Jul 27, 2018
    ural and jahswani like this.
  2. Sandman

    Sandman Well-Known Member Licensed User

    It might be worth mentioning that your method is actually destroying the image quality as it doesn't consider the transparancy values. It's easy to see in the pic you posted, the edges of the white house (the original) are very smooth, because there's lots of different levels of transparancy there. The edges of the green house looks very rough.

    Thankfully this is simple to fix. Stop using IsTransparent, as that only answers whether the pixel is completely transparent. Instead use a method that gives the level of transparancy and multiply that with clr. That will produce a perfect result.
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    [​IMG]

    Code:
    Sub Activity_Create(FirstTime As Boolean)
       
    Activity.LoadLayout("1")
       
    Dim xui As XUI
       
    Dim bmp As B4XBitmap = xui.LoadBitmap(File.DirAssets, "baseline_settings_phone_black_48dp.png")
       SetBitmapWithFitOrFill(ImageView1, bmp)
       SetBitmapWithFitOrFill(ImageView2, ChangeColorBasedOnAlphaLevel(bmp, xui.Color_Red))
       SetBitmapWithFitOrFill(ImageView3, ChangeColorBasedOnAlphaLevel(bmp, xui.Color_Blue))
       SetBitmapWithFitOrFill(ImageView4, ChangeColorBasedOnAlphaLevel(bmp, xui.Color_Green))
       SetBitmapWithFitOrFill(ImageView5, ChangeColorBasedOnAlphaLevel(bmp, 
    0xFFA30075))
       SetBitmapWithFitOrFill(ImageView6, ChangeColorBasedOnAlphaLevel(bmp, 
    0xFF00FFE7))
    End Sub

    Sub ChangeColorBasedOnAlphaLevel(bmp As B4XBitmap, NewColor As Int) As B4XBitmap
       
    Dim bc As BitmapCreator
       bc.Initialize(bmp.Width, bmp.Height)
       bc.CopyPixelsFromBitmap(bmp)
       
    Dim a1, a2 As ARGBColor
       bc.ColorToARGB(NewColor, a1)
       
    For y = 0 To bc.mHeight - 1
           
    For x = 0 To bc.mWidth - 1
               bc.GetARGB(x, y, a2)
               
    If a2.a > 0 Then
                   a2.r = a1.r
                   a2.g = a1.g
                   a2.b = a1.b
                   bc.SetARGB(x, y, a2)
               
    End If
           
    Next
       
    Next
       
    Return bc.Bitmap
    End Sub

    Public Sub SetBitmapWithFitOrFill (vTargetView As B4XView, bmp As B4XBitmap)
       vTargetView.SetBitmap(bmp)
       
    #if B4A
       
    'B4XView.SetBitmap sets the gravity in B4A to CENTER. This will prevent the bitmap from being scaled as needed so
       'we switch to FILL
       Dim iv As ImageView = vTargetView
       iv.Gravity = 
    Gravity.FILL
       
    #End If
    End Sub
    I'm using SetBitmapWithFitOrFill as the icon size is actually 96x96 and the ImageViews are 48x48. This provides better results.
    We can also use Bitmap.Resize to resize the image however the performance of SetBitmapWithFitOrFill is better (in most cases it doesn't really matter).
     
    ural, beacon, Peter Simpson and 5 others like this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice