B4J Question [solved] Sending Images From Server

Squiffy

Active Member
Licensed User
Longtime User
When I serve a static page I have to handle the various requests for JS, CSS and the like that hit the server. They are easy as they are just text files which I can Write out (I create handlers for the subdirectories like css/...and just write their contents to the ServletResponse)

But how to send, for example, myimage.jpg?
 

Squiffy

Active Member
Licensed User
Longtime User
Looks like I need to set headers like this :

B4X:
HTTP/1.1200 OK
Content-Type: image/jpegContent-Length:*length of image*

BinaryImageData goes here

And convert the image to raw bytes.

Looking all that up now ...
 
Upvote 0

Squiffy

Active Member
Licensed User
Longtime User
Be grateful if someone could point me the right way....

B4X:
        Dim f As InputStream
        f=File.OpenInput(Main.srvr.StaticFilesFolder,url) ' This points to the correct file, I'm sure.
       
        Dim ba As Int = f.BytesAvailable
        Log("Bytes Available for " & url & "=" & ba) ' Shows correct byte size.

        Dim buffer(ba) As Byte
        f.ReadBytes(buffer,0,buffer.Length)
              
        Dim bc As ByteConverter
        Dim bufferText As String

        ' Tried all sorts here.
        'bufferText = bc.StringFromBytes(buffer,"UTF-8") 
        'bufferText = bc.HexFromBytes(buffer)

        'Dim su As StringUtils
        'bufferText=su.EncodeBase64(buffer)

        resp.ContentType="image/jpeg"
        resp.ContentLength=bufferText.Length
        resp.Write(bufferText)

Console in browser shows : Resource interpreted as document but sent as MIME type image/jpeg

The payload seems to be there in all cases. No other errors that i can see, but the image doesn't display.
 
Upvote 0

Squiffy

Active Member
Licensed User
Longtime User
Got there in the end!

B4X:
        Dim f As InputStream
        f=File.OpenInput(Main.srvr.StaticFilesFolder,url)
      
        Dim ba As Int = f.BytesAvailable
        Dim buffer(ba) As Byte
        f.ReadBytes(buffer,0,ba)
      
        resp.ContentType="image/jpeg"
        resp.ContentLength=buffer.Length
      
        resp.OutputStream.WriteBytes(buffer,0,ba)

Works like a charm, though worth noting that BytesAvailable might not always be accurate. According to the docs it takes an estimate as it's non blocking. I imagine I will need a more robust way of reading the file in production to ensure I'm getting it all.
 
Last edited:
Upvote 0

Harris

Expert
Licensed User
Longtime User
Got there in the end!

B4X:
        Dim f As InputStream
        f=File.OpenInput(Main.srvr.StaticFilesFolder,url)
     
        Dim ba As Int = f.BytesAvailable
        Dim buffer(ba) As Byte
        f.ReadBytes(buffer,0,ba)
     
        resp.ContentType="image/jpeg"
        resp.ContentLength=buffer.Length
     
        resp.OutputStream.WriteBytes(buffer,0,ba)

Works like a charm, though worth noting that BytesAvailable might not always be accurate. According to the docs it takes an estimate as it's non blocking. I imagine I will need a more robust way of reading the file in production to ensure I'm getting it all.
I think I recall the byte buffer will increase accordingly. I generally just init to 1000 - regardless of file size.
 
Upvote 0

Squiffy

Active Member
Licensed User
Longtime User
I was thinking more about the reading in of the file. If the "estimate" is low then we won't have all of it.
Seems to work perfectly at the moment, but I'm only loading files of about 6k.
 
Upvote 0
Top