Android Question webview - get a bitmap with javascript

yo3ggx

Active Member
Licensed User
Longtime User
I want to extract the image in a bitmap using a webview and javascript commands.
The code on the web page looks like that:



B4X:
<canvas class="mypic" id="mpcanvas0" width="1024" height="100" >test</canvas>

The image is dynamically changed. If I try:

B4X:
Dim js As String
js = $"B4A.CallSub('pic_cb', true, document.getElementById('mpcanvas0'));"$
WebViewExtrasSDR.executeJavascript(WebView1,text)

Sub pic_cb(b As Object)
    Log("canvas")
End Sub
The routine is called only one time and I don't know what type of object is returned as is not a Canvas.

Thank you
 

yo3ggx

Active Member
Licensed User
Longtime User
If I use:
B4X:
document.getElementById('mpcanvas0').toDataURL()

returned value is a string containing the png file in base64 format:

"data:image/png;base64,iVBORw0KGgoAAAANSUhEUg......."
 
Upvote 0

TILogistic

Expert
Licensed User
Longtime User
To get or set the desired element, you can use this B4X routine.
B4X:
Private Sub RunJavaScript (js As String) As ResumableSub
    #if B4A
    WebViewExtras1.executeJavascript(WebView1, $"B4A.CallSub('Process_HTML', true, ${js})"$)
    Wait For Process_Html(html As String)
    Return html
    #Else If B4J
    Return WebView1.As(JavaObject).RunMethodJO("getEngine", Null).RunMethod("executeScript", Array(js))
    #Else If B4i
    Dim sf As Object = WebView1.EvaluateJavaScript(js)
    Wait For (sf) WebView1_JSComplete (Success As Boolean, Result As String)
    Return Result
    #end if
End Sub
ref:
 
Last edited:
Upvote 0

TILogistic

Expert
Licensed User
Longtime User
you can use StringUtils to convert base64 to image or image to base64

"data:image/png;base64,iVBORw0KGgoAAAANSUhEUg......."

1674263308293.png
 
Last edited:
Upvote 0

yo3ggx

Active Member
Licensed User
Longtime User
To get or set the desired element, you can use this B4X routine.
This is what I already did. The problem is that I just got a snapshot of the dynamic image from the moment the procedure was run. What I want is to get the dynamic image and display it on a canvas in my app, not in the WebView (which is not even added to the activity). I can do this by polling, but for sure will not be in sync with the updates in the web page.
How I can call a sub in B4A when the image from the web page is updated?
 
Last edited:
Upvote 0

TILogistic

Expert
Licensed User
Longtime User
This is what I already did. The problem is that I just got a snapshot of the dynamic image from the moment the procedure was run. What I want is to get the dynamic image and display it on a canvas in my app, not in the WebView (which is not even added to the activity). I can do this by polling, but for sure will not be in sync with the updates in the web page.
How I can call a sub in B4A when the image from the web page is updated?
post a small example of what you want to do, so they can help you.

If you capture the url of the image that is encoded in base64 you just have to convert it (binary) and display it wherever you want.

To update the page or web element you have to convert the image to base64 with B4X or through javascrits
 
Upvote 0

yo3ggx

Active Member
Licensed User
Longtime User
post a small example of what you want to do, so they can help you.
This is what I did in my initial and second post.
What is working: extracting the bitmap in png format and display it on a Canvas in my app.
What I don't know how to do: Create some kind of callback when the image is updated on the web page, to dynamically and synchronously update the image on my canvas (without using async polling).
 
Upvote 0

TILogistic

Expert
Licensed User
Longtime User
This is what I did in my initial and second post.
What is working: extracting the bitmap in png format and display it on a Canvas in my app.
What I don't know how to do: Create some kind of callback when the image is updated on the web page, to dynamically and synchronously update the image on my canvas (without using async polling).
where is the website and how do you access it if you don't use webview?

What parameters do you have to know if the image is updated on the web page?
 
Upvote 0

yo3ggx

Active Member
Licensed User
Longtime User
where is the website and how do you access it if you don't use webview?

What parameters do you have to know if the image is updated on the web page?
I think is a misunderstanding. Of course I access it using a Webview, but that WebView is not added to the Activity (with Activity.AddView(WebView1,l,t,w,h)). Is just initialized and configured. I want the dynamic image from the web page to be displayed in a canvas in my app, without displaying the full WebView. Currently I can only display a snapshot of that image.
 
Upvote 0

TILogistic

Expert
Licensed User
Longtime User
You now know how to capture the image of the web page element.

Now you want to know how to update the image (bitmap) from the one you captured (html) when the image changes on the web.

The question.
What web page parameters do you know that can tell you that the image has changed?
 
Upvote 0

TILogistic

Expert
Licensed User
Longtime User
see the following post, how javascript functions are executed


It can be a guide to add an "onload" event (addEventListener) of images
 
Upvote 0

yo3ggx

Active Member
Licensed User
Longtime User
see the following post, how javascript functions are executed
If I try the example from webnew2.zip, I can see the video on top when clicking on play, I can capture a screenshot, bot not live video.
In your example you create a canvas with the screenshot. In my case I have the canvas which is dynamically updated.
 
Last edited:
Upvote 0

yo3ggx

Active Member
Licensed User
Longtime User
There is no event triggered by a canvas draw. Onload event is not triggered.
As I'm not displaying the WebView anyway, there is any possibility to redirect canvas updates from the webview to my own to canvas?
or (I'm thinking loud)
I can crop the WebView to show only the desired canvas?
 
Upvote 0

yo3ggx

Active Member
Licensed User
Longtime User
It looks like polling is fast enough for my needs even on older Android versions (5.0), so for the moment I will use this approach.
For very low performance and old devices, I can decrease the quality of the downloaded image from 1 to 0.5.
 
Upvote 0
Top