B4J Question Draw shape with alpha transparency ?

hookshy

Well-Known Member
Licensed User
Longtime User
I want to draw shapes with canvas and I did not managed to get the alpha transparency efect !

I can draw any shape but the bitmap is on white opac color !

How do you get the alpa transparency on a nonrectangular shape using canvas ?
 

hookshy

Well-Known Member
Licensed User
Longtime User
the below code draws an horizontal pipe but the background is white , this actually works as long as the objects behind the pipe are on white backgound as well ..otherwise I have to make all field outside the shape transparent !

I need the imageview width and height to because I will resize the pipe shape using canvas .
B4X:
Sub horizontal(c As Canvas,clone As ImageView) As Image

'set the correct canvas dimension
c.Width=clone.Width
c.Height=clone.Height

'clear canvas

'c.ClearRect(0,0,c.Width,c.Height)

' draw shape
Dim w,h,lp,hp,gros,flansa As Int
gros=1dip
flansa=5dip

w=c.Width
h=c.Height-2*gros
lp=w-2*flansa
hp=0.8*h

c.DrawRect(0,0,flansa,h,fx.Colors.ARGB(100,100,100,100),False,gros)
c.DrawRect(flansa,h/2-hp/2,lp,hp,fx.Colors.ARGB(100,100,100,100),False,gros)
c.DrawRect(w-flansa,0,flansa,h,fx.Colors.ARGB(100,100,100,100),False,gros)


Return c.Snapshot

End Sub
 
Upvote 0

hookshy

Well-Known Member
Licensed User
Longtime User
I tried to set the canvas style but It does not seem to help much
Is this the correct way to make the canvas background transparent because the c.snapshot is returning an white opac background !

B4X:
c.Style="-fx-background-color: #000000;"
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
This might give you a few pointers
B4X:
    MainForm = Form1
    MainForm.Show
    MainForm.BackColor = fx.Colors.Cyan                        ' so we can see if background is transparent
    im.Initialize("")                                         ' image view
    can.Initialize("")                                         ' canvas object
    Dim jo,gc,g As JavaObject
    jo = can                                                ' canvas
    jo.RunMethod("setWidth",Array(200.0))                     ' set width 
    jo.RunMethod("setHeight",Array(200.0))                    ' set height
    MainForm.RootPane.AddNode(can,0,0,200,200)                ' add to mainform
    MainForm.RootPane.AddNode(im,200,0,200,200)                ' add to mainform
    gc = jo.RunMethod("getGraphicsContext2D",Null)          ' get graphics context
    gc.RunMethod("clearRect",Array(0.0,0.0,200.0,200.0))    ' clear canvas to transparent
    gc.RunMethod("setFill",Array(fx.Colors.LightGray))        ' make a grey box
    gc.RunMethod("fillRect",Array(10.0,10.0,25.0,25.0))        ' draw the box
    gc.RunMethod("setStroke",Array(fx.Colors.Red))            ' set color for line
    gc.RunMethod("setLineWidth",Array(2.0))                    ' set line width
    gc.RunMethod("strokeLine",Array(100.0,100.0,150.0,175.0))' draw the line
    g.InitializeNewInstance("javafx.scene.SnapshotParameters",Null) ' javaobject
    g.RunMethod("setFill",Array(fx.Colors.Transparent))     ' set snapshot parameter to trans background
    im.SetImage(jo.RunMethod("snapshot",Array(g,Null)))     ' the snap shot
 
Upvote 0

hookshy

Well-Known Member
Licensed User
Longtime User
I guess your example will work ! thank you .. I did not test it to the end because I do not know how to draw with runmethod
...as I need to draw a complex shapes
I must be more documented on RunMethod
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
The gc.RunMethod(...) simply allows you to invoke the functions of the 'GraphicsContext2D' (the canvas object) directly by use of a javaobject.
There is a similar thread (at top of this page Canvas Snapshot and transparency), the B4J snapshot cannot deal with a transparent background, you have to set the snapshot parameters, then invoke the snapshot routine using the snapshot parameters.
 
Upvote 0

hookshy

Well-Known Member
Licensed User
Longtime User
GraphicsContext2D

arrow drawn with GraphicsContext2D

B4X:
Sub deco_l(c As Canvas,clone As ImageView,color As Paint) As Image

    Dim jo,gc,g As JavaObject
    jo = c                                              ' canvas
    jo.RunMethod("setWidth",Array(clone.Width))                     ' set width
    jo.RunMethod("setHeight",Array(clone.Height))                    ' set height
 

    gc = jo.RunMethod("getGraphicsContext2D",Null)          ' get graphics context
    gc.RunMethod("clearRect",Array(0.0,0.0,clone.Width,clone.Height))    ' clear canvas to transparent
    gc.RunMethod("setFill",Array(color))        ' make a grey box

Dim yi,hf,arr As Double
yi=0.25*clone.Height
hf=0.75*clone.Height
arr=0.75*clone.Width

'building a path that looks like an arrow
Dim path As List
path.Initialize

gc.RunMethod("beginPath",Null)
gc.RunMethod("moveTo",Array(0.0,yi))

gc.RunMethod("lineTo",Array(0.0,hf))

gc.RunMethod("lineTo",Array(arr,hf))
gc.RunMethod("lineTo",Array(arr,c.Height))


gc.RunMethod("lineTo",Array(c.Width,c.Height/2))
gc.RunMethod("lineTo",Array(arr,0.0))

gc.RunMethod("lineTo",Array(arr,yi))
gc.RunMethod("lineTo",Array(0.0,yi))

gc.RunMethod("closePath",Null)
gc.RunMethod("fill",Null)

   gc.RunMethod("rotate",Array(180.00))'????????

    g.InitializeNewInstance("javafx.scene.SnapshotParameters",Null) ' javaobject
    g.RunMethod("setFill",Array(fx.Colors.Transparent))     ' set snapshot parameter to trans background

Return jo.RunMethod("snapshot",Array(g,Null))
 
Last edited:
Upvote 0

hookshy

Well-Known Member
Licensed User
Longtime User
I did use your code and it seem I can use canvas from b4j afterall ...and the reason I prefer to use B4j is that is faster than puting parrameters
all though there are some limitations.

'the below code draws a upward arrow with a transparent background

B4X:
Sub deco_u(c As Canvas,clone As ImageView,color As Paint) As Image

c.Width=clone.Width
c.Height=clone.Height

'clear canvas
c.ClearRect(0,0,c.Width,c.Height)

Dim wi,wf,arr As Int
wi=0.25*c.Width
wf=0.75*c.Width
arr=0.25*c.Height

Dim path As List
path.Initialize

path.Add(Array As Double(c.Width/2,0))

path.Add(Array As Double(0,arr))
path.Add(Array As Double(wi,arr))

path.Add(Array As Double(wi,c.Height))
path.Add(Array As Double(wf,c.Height))

path.Add(Array As Double(wf,arr))
path.Add(Array As Double(c.Width,arr))


path.Add(Array As Double(c.Width/2,0))

c.ClipPath(path)

c.DrawRect(0,0,c.Width,c.Height,color,True,0)

c.RemoveClip

'the code below replace ...c.snapshot that was returning opac background

    Dim g As JavaObject
    g.InitializeNewInstance("javafx.scene.SnapshotParameters",Null) ' javaobject
    Dim p As Paint = fx.Colors.Transparent
    g.RunMethod("setFill",Array As Object(p))
   
    Dim jot As JavaObject
    jot = c ' contains the canvas object
   
    Dim im As Image
    im = jot.RunMethod("snapshot",Array As Object(g,Null)) ' im = Image

    Return im
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Sorry if my example code misled you, yes you draw on canvas normally with b4j, it's just the snapshot part that needs changing.
 
Upvote 0

hookshy

Well-Known Member
Licensed User
Longtime User
Sorry if my example code misled you, yes you draw on canvas normally with b4j, it's just the snapshot part that needs changing.
Not a problem , as I discovered more usage of java object .
If I would not have asked the question first place I would not found the answer.
Thank you for help
 
Upvote 0
Top