Android Code Snippet [B4X] [BitmapCreator] Blur Image

Returns a blurred image:

SS-2018-05-13_11.30.54.png


Code: Copy
Private Sub Blur (bmp As B4XBitmap) As B4XBitmap
   Dim n As Long = DateTime.Now
   Dim bc As BitmapCreator
   Dim ReduceScale As Int = 2
   bc.Initialize(bmp.Width / ReduceScale / bmp.Scale, bmp.Height / ReduceScale / bmp.Scale)
   bc.CopyPixelsFromBitmap(bmp)
   Dim count As Int = 3
   Dim clrs(3) As ARGBColor
   Dim temp As ARGBColor
   Dim m As Int
   For steps = 1 To count
       For y = 0 To bc.mHeight - 1
           For x = 0 To 2
               bc.GetARGB(x, y, clrs(x))
           Next
           SetAvg(bc, 1, y, clrs, temp)
           m = 0
           For x = 2 To bc.mWidth - 2
               bc.GetARGB(x + 1, y, clrs(m))
               m = (m + 1) Mod clrs.Length
               SetAvg(bc, x, y, clrs, temp)
           Next
       Next
       For x = 0 To bc.mWidth - 1
           For y = 0 To 2
               bc.GetARGB(x, y, clrs(y))
           Next
           SetAvg(bc, x, 1, clrs, temp)
           m = 0
           For y = 2 To bc.mHeight - 2
               bc.GetARGB(x, y + 1, clrs(m))
               m = (m + 1) Mod clrs.Length
               SetAvg(bc, x, y, clrs, temp)
           Next
       Next
   Next
   Log(DateTime.Now - n)
   Return bc.Bitmap
End Sub

Private Sub SetAvg(bc As BitmapCreator, x As Int, y As Int, clrs() As ARGBColor, temp As ARGBColor)
   temp.Initialize
   For Each c As ARGBColor In clrs
       temp.r = temp.r + c.r
       temp.g = temp.g + c.g
       temp.b = temp.b + c.b
   Next
   temp.a = 255
   temp.r = temp.r / clrs.Length
   temp.g = temp.g / clrs.Length
   temp.b = temp.b / clrs.Length
   bc.SetARGB(x, y, temp)
End Sub

Usage example:

Code: Copy
Dim bmp As B4XBitmap = xui.LoadBitmapResize(File.DirAssets, "bas-van-brandwijk-588535-unsplash.jpg", ImageView1.Width, ImageView1.Height, True)
ImageView1.SetBitmap(Blur(bmp))

Depends on: BitmapCreator and XUI libraries

Update: The previous code incorrectly scaled the bitmap based on the device scale. It should be based on the bitmap scale instead:
Code: Copy
bc.Initialize(bmp.Width / ReduceScale / bmp.Scale, bmp.Height / ReduceScale / bmp.Scale)
B4XBitmap.Scale is included in XUI v1.70 which will be released in a day or two.
 
Last edited:
Returns a blurred image:
Code: Copy
Private Sub Blur (bmp As B4XBitmap) As B4XBitmap
   Dim n As Long = DateTime.Now
   Dim bc As BitmapCreator
   Dim ReduceScale As Int = 2
   bc.Initialize(bmp.Width / ReduceScale / bmp.Scale, bmp.Height / ReduceScale / bmp.Scale)
   bc.CopyPixelsFromBitmap(bmp)
   Dim count As Int = 3
   Dim clrs(3) As ARGBColor
   Dim temp As ARGBColor
   Dim m As Int
   For steps = 1 To count
       For y = 0 To bc.mHeight - 1
           For x = 0 To 2
               bc.GetARGB(x, y, clrs(x))
           Next
           SetAvg(bc, 1, y, clrs, temp)
           m = 0
           For x = 2 To bc.mWidth - 2
               bc.GetARGB(x + 1, y, clrs(m))
               m = (m + 1) Mod clrs.Length
               SetAvg(bc, x, y, clrs, temp)
           Next
       Next
       For x = 0 To bc.mWidth - 1
           For y = 0 To 2
               bc.GetARGB(x, y, clrs(y))
           Next
           SetAvg(bc, x, 1, clrs, temp)
           m = 0
           For y = 2 To bc.mHeight - 2
               bc.GetARGB(x, y + 1, clrs(m))
               m = (m + 1) Mod clrs.Length
               SetAvg(bc, x, y, clrs, temp)
           Next
       Next
   Next
   Log(DateTime.Now - n)
   Return bc.Bitmap
End Sub

Private Sub SetAvg(bc As BitmapCreator, x As Int, y As Int, clrs() As ARGBColor, temp As ARGBColor)
   temp.Initialize
   For Each c As ARGBColor In clrs
       temp.r = temp.r + c.r
       temp.g = temp.g + c.g
       temp.b = temp.b + c.b
   Next
   temp.a = 255
   temp.r = temp.r / clrs.Length
   temp.g = temp.g / clrs.Length
   temp.b = temp.b / clrs.Length
   bc.SetARGB(x, y, temp)
End Sub

Usage example:

Code: Copy
Dim bmp As B4XBitmap = xui.LoadBitmapResize(File.DirAssets, "bas-van-brandwijk-588535-unsplash.jpg", ImageView1.Width, ImageView1.Height, True)
ImageView1.SetBitmap(Blur(bmp))

Depends on: BitmapCreator and XUI libraries

Update: The previous code incorrectly scaled the bitmap based on the device scale. It should be based on the bitmap scale instead:
Code: Copy
bc.Initialize(bmp.Width / ReduceScale / bmp.Scale, bmp.Height / ReduceScale / bmp.Scale)
B4XBitmap.Scale is included in XUI v1.70 which will be released in a day or two.
We are wait XUI v1.70 :-p
 
File PNG - B4XImageView

1793377287972.png


To resolve the black background issue, you need to modify Sub SetAvg so:
Code: Copy
Private Sub SetAvg(bc As BitmapCreator, x As Int, y As Int, clrs() As ARGBColor, temp As ARGBColor)
    temp.Initialize

    For Each c As ARGBColor In clrs
        temp.r = temp.r + c.r
        temp.g = temp.g + c.g
        temp.b = temp.b + c.b
        temp.a = temp.a + c.a
    Next

    temp.a = temp.a / clrs.Length
    temp.r = temp.r / clrs.Length
    temp.g = temp.g / clrs.Length
    temp.b = temp.b / clrs.Length

    bc.SetARGB(x, y, temp)
End Sub
 
can you enhance the blur effect? which value do I have to increase for this?
Code: Copy
' Returns a blurred bitmap according to Intensity (0-100).
Private Sub Blur(bmp As B4XBitmap, Intensity As Int = 50) As B4XBitmap
    Intensity = Max(0, Min(100, Intensity))
    If Intensity = 0 Then Return bmp

    Dim ReduceScale As Int = 2
    Dim count As Int = Max(1, Intensity * 20 / 100)

    Dim bc As BitmapCreator
    bc.Initialize(bmp.Width / ReduceScale / bmp.Scale, bmp.Height / ReduceScale / bmp.Scale)
    bc.CopyPixelsFromBitmap(bmp)

    Dim clrs(3) As ARGBColor
    Dim temp As ARGBColor
    Dim m As Int

    For steps = 1 To count

        ' Horizontal blur.
        For y = 0 To bc.mHeight - 1
            For x = 0 To 2
                bc.GetARGB(x, y, clrs(x))
            Next

            SetAvg(bc, 1, y, clrs, temp)

            m = 0
            For x = 2 To bc.mWidth - 2
                bc.GetARGB(x + 1, y, clrs(m))
                m = (m + 1) Mod clrs.Length
                SetAvg(bc, x, y, clrs, temp)
            Next
        Next

        ' Vertical blur.
        For x = 0 To bc.mWidth - 1
            For y = 0 To 2
                bc.GetARGB(x, y, clrs(y))
            Next

            SetAvg(bc, x, 1, clrs, temp)

            m = 0
            For y = 2 To bc.mHeight - 2
                bc.GetARGB(x, y + 1, clrs(m))
                m = (m + 1) Mod clrs.Length
                SetAvg(bc, x, y, clrs, temp)
            Next
        Next

    Next

    Return bc.Bitmap
End Sub

java_fghiAw1OIS.gif
 
Which of these mathematical functions does your function use?

  • Gaussian Blur
  • Box Blur
  • Average Blur
  • Median Blur
  • Stack Blur
  • Fast Blur
 
Back
Top