Android Question Is there a way to change how bitmaps with an alpha channel are drawn?

NeoTechni

Well-Known Member
Licensed User
Longtime User
I want to make a graphics editing program for Galaxy Notes, and the main thing for such a program would be a paint brush tool. But that tool requires a way to draw shapes with transparency, over each other without a visible intersection.

ie: new alpha of a pixel = the larger of the existing alpha, and the alpha of a pixel being drawn on top of it.
ALPHA3=MAX(ALPHA1, ALPHA2)

But the current drawbitmap sub just draws them over top of each other
ie: ALPHA3=ALPHA1+ALPHA2

(The red dot is just an example, I'd need it to work for any image with transparency/translucency)

I could do the math myself, drawing it pixel by pixel, but that is A LOT slower.
 

Attachments

  • Untitled.png
    Untitled.png
    31 KB · Views: 293

NeoTechni

Well-Known Member
Licensed User
Longtime User
I didn't think it'd be this fast, but I did it pixel by pixel

B4X:
'TransferMode: 0=MAX(Src,Dest)
Sub MergeAlphaLayers(DestImage As Bitmap, SrcBrush As Bitmap, DestX As Int, DestY As Int, Center As Boolean, TransferMode As Int) As Boolean
   Dim Width As Int = SrcBrush.Width, Height As Int = SrcBrush.Height, tempX As Int, tempY As Int, SrcX As Int, SrcY As Int, SrcAlpha As Int, DestAlpha As Int
   If Center Then
     DestX = DestX - SrcBrush.Width * 0.5
     DestY = DestY - SrcBrush.Height * 0.5  
   End If
   If DestX > DestImage.Width Or DestY > DestImage.Height Then Return False
   If DestX < 0 Then
     SrcX = Abs(DestX)
     Width = Width - SrcX
     DestX = 0
   End If
   If DestY < 0 Then
     SrcY = Abs(DestY)
     Height = Height - SrcY
     DestY = 0
   End If
   tempX = DestX + Width
   If tempX > DestImage.Width Then Width = Width - (tempX - DestImage.Width)
   tempY = DestY + Height
   If tempY > DestImage.Height Then Height = Height - (tempY - DestImage.Height)
   If Width < 1 Or Height < 1 Then Return False
   Dim Pixels As Int = Width*Height, DestPixels(Pixels) As Int, SrcPixels(Pixels) As Int, ExDraw As ABExtDrawing = LCAR.ExDraw', tempSrcX As Int, tempSrcY As Int = SrcY, tempDestX As Int, tempDestY As Int = DestY
   ExDraw.getPixels(SrcBrush, SrcPixels, 0, Width, SrcX,SrcY,Width,Height)
   ExDraw.getPixels(DestImage, DestPixels, 0, Width, DestX,DestY,Width,Height)
   For tempX = 0 To Pixels - 1
     SrcAlpha = GetARGB(SrcPixels(tempX), 0)
     If SrcAlpha > 0 Then
       DestAlpha = GetARGB(DestPixels(tempX), 0)
       Select Case TransferMode
         Case 0
           DestPixels(tempX) = SetARGB(SrcPixels(tempX), 0, Max(SrcAlpha, DestAlpha))
       End Select
     End If
   Next
   ExDraw.setPixels(DestImage, DestPixels, 0, Width, DestX, DestY, Width, Height)
   Return True
End Sub


'Channel: 0=A, 1=R, 2=G, 3=B
'Replaces the byte of the ARGB channel with Value (which must be 0-255)
Sub SetARGB(Color As Int, Channel As Int, Value As Int) As Int
   Value = Max(0,Min(Value,255))
   Select Case Channel
     Case 0'Alpha
       Color = Bit.And(Color, 0x00ffffff)
       Value = Bit.ShiftLeft(Value, 24)
     Case 1'Red
       Color = Bit.And(Color, 0xff00ffff)
       Value = Bit.ShiftLeft(Value, 16)
     Case 2'Green
       Color = Bit.And(Color, 0xffff00ff)
       Value = Bit.ShiftLeft(Value, 8)
     Case 3'Blue
       Color = Bit.And(Color, 0xffffff00)
   End Select
   Return Bit.Or(Color,Value)
End Sub

'Channel: 0=A, 1=R, 2=G, 3=B
Sub GetARGB(Color As Int, Channel As Int) As Int
  Select Case Channel
     Case 0: Return Bit.UnsignedShiftRight(Bit.And(Color, 0xff000000), 24)'A
     Case 1: Return Bit.UnsignedShiftRight(Bit.And(Color, 0xff0000), 16)'R
     Case 2: Return Bit.UnsignedShiftRight(Bit.And(Color, 0xff00), 8)'G
     Case 3: Return Bit.And(Color, 0xff)'B
  End Select
End Sub
 
Upvote 0

NeoTechni

Well-Known Member
Licensed User
Longtime User
That's the exact opposite of what I wanted though. The intersection is what I DIDNT want
 
Upvote 0
Top