B4J Question Webserver Updating Image

TomDuncan

Active Member
Licensed User
Longtime User
Hi All,
Still working on my server.
B4J running on a windows machine.
Weather from a station at my place.
Images from Ip-Camera out the front.
I can update the weather info using websockets.
I also check if a new image has been sent via ftp.
If so it changes the src link.
This all works well accept the image flashes when it does a refresh.
This is only once per minute but a pain.
Any thoughts on how to do an html image refresh.
Have a look at.
http://ctd.noip.me

Tom
 

Cableguy

Expert
Licensed User
Longtime User
From what I could see, you are refreshingthe whole page...
Are you using ABMaterial? If so, you can refresh the image only!
 
Upvote 0

TomDuncan

Active Member
Licensed User
Longtime User
No, refreshing each area only.
Using websockets to do the updating.
The image and it's border are created if their has been a change.
I have put in a dark routine, so no image updates while it is dark.
Tom
 
Upvote 0

TomDuncan

Active Member
Licensed User
Longtime User
Have changed the code to update every 30 secs and take out the dark routines.
Just for checking.
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
I'm only getting a black image with the camera info on top...
I'm in France (GMT+1)
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
Oh, ok... I'm using my phone so they're not that visible... I get no flickering this time, but since I have an almost completely dark image, I can't say for sure if it's solved
 
Upvote 0

TomDuncan

Active Member
Licensed User
Longtime User
Not sure where to use this code.
At the moment I am updating using a websockets.
Where do I put in the base64 load function?

Tom
 
Upvote 0

TomDuncan

Active Member
Licensed User
Longtime User
Have had a look at what Erel had said.
Bit out of my knowledge but this is what I have and what I tried.

B4X:
' Working version

' LastImage is the filename for the image to be displayed
dim T as String = "$
    <div class="w3-card-4">
        <img src="../view/"$ & Main.lastImage & $"" alt="Huon RiverView" style="width:100%">
        <footer class="w3-container w3-theme-l1">
            <h5>Live image. Refreshed every 30 secs for thge moment.</h5>
        </footer>
    </div>"$

current_image.SetHtml(T)

' my attempt to do what was done with the getimage routine
' oops

Dim img() As Byte = "../view/" & Main.lastImage
Dim T As String = $"
    <div class="w3-card-4">
        <img width=100% src='data:image/png;base64,'"$
T = T &  su.EncodeBase64(img) & "'/img>"
T = T & $"
        <footer class="w3-container w3-theme-l1">
            <h5>Live image. Refreshed every 30 secs For thge moment.</h5>
        </footer>
    </div>
"$
current_image.SetHtml(T)

Need help on doing the encoding.

Tom
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
If the image is already in a byte array you can probably do

B4X:
Dim T As String = $"
 <div class="w3-card-4">
    <img width=100% src="data:image/png;base64,${su.EncodeBase64(img)}">
    <footer class="w3-container w3-theme-l1">
       <h5>Live image. Refreshed every 30 secs For the moment.</h5>
    </footer>
 </div>
"$
 
Upvote 0

TomDuncan

Active Member
Licensed User
Longtime User
The image has been ftp transferred from the ip-camera and is a file.
How do I make a byte array from this file?
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Is it a png file ?
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Sorry for delay - was writing the code in a ui program so had to make sure I didn't use any javafx routines.
This should do what you need
The code to read the image and convert to byte array representation of a png image
B4X:
#if java
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.*;
public static byte[] imageToBytes(String filename,String ext) throws IOException{
BufferedImage img = null;
  img = ImageIO.read(new File(filename));
ByteArrayOutputStream s = new ByteArrayOutputStream();
ImageIO.write(img, ext, s);
byte[] res  = s.toByteArray();
s.close();
return res;
}
#end if

How to call it
B4X:
Dim T As String = $"
<div class="w3-card-4">
  <img width=50% src="data:image/png;base64,${su.EncodeBase64(asJO(Me).RunMethod("imageToBytes",Array("c:/temp/treeviewchecks.png","png")))}">
  <footer class="w3-container w3-theme-l1">
  <h5>Live image. Refreshed every 30 secs For the moment.</h5>
  </footer>
</div>
"$
....
End Sub
Sub asJO(o As JavaObject)As JavaObject
Return o
End Sub

The java part will read the file and return a byte array of the data

The B4J part will call the java with the filename and extension name and insert the Base64 encoded data into the html.
As you are using image/png - pass "png" as the extension. (although it doesn't matter what you pass)

Hope this helps :)
BTW, the file can be png, bmp or jpg - it will convert them all.
 
Last edited:
Upvote 0

TomDuncan

Active Member
Licensed User
Longtime User
Thanks for that.
The flash does not seems as bad.
This is what I did. It works so maybe I did what I was told.

B4X:
        Dim Foot As String = "Live image. Refreshed every minute."
        If (old_image <> Main.viewimage) And Main.viewimage.Contains(".jpg") Then

                old_image = Main.viewimage
                DateTime.DateFormat="yyyyMMdd"
                folder_image = DateTime.Date(DateTime.Now)
            Main.lastImage = folder_image & "/images/" & old_image

            Dim pointy As String = "\\BRIX\www\view\" & DateTime.Date(DateTime.Now) & "\images\" & old_image
           
        Dim T As String = $"
<div class="w3-card-4">
  <img width=100% src="data:image/png;base64,${su.EncodeBase64(asJO(Me).RunMethod("imageToBytes",Array(pointy,"png")))}">
  <footer class="w3-container w3-theme-l1">
  <h5>Live image. Refreshed every 30 secs For the moment.</h5>
  </footer>
</div>
"$

        current_image.SetHtml(T)

        End If
    End If
   
    DateTime.DateFormat="yy/MM/dd"
    DateTime.TimeFormat="HH:mm:ss"
    todaysdate.SetHtml("&nbsp;&nbsp;Local Time on " & DateTime.Date(DateTime.Now) & " at Police Point, Tasmania, Australia is <b>  " & DateTime.Time(DateTime.Now) & "</b>")
    ws.Flush 'required here as this is a server event
    WeatherCount = WeatherCount + 1
    If WeatherCount = 20 Then WeatherCount = 1
End Sub

#if java
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.*;
public static byte[] imageToBytes(String filename,String ext) throws IOException{
BufferedImage img = null;
  img = ImageIO.read(new File(filename));
ByteArrayOutputStream s = new ByteArrayOutputStream();
ImageIO.write(img, ext, s);
byte[] res  = s.toByteArray();
s.close();
return res;
}
#end if

Sub asJO(o As JavaObject)As JavaObject
    Return o
End Sub

Tom
 
Upvote 0
Top