Android Question [SOLVED] Image receiving via Bluetooth

TomKluz

Active Member
Licensed User
Hello,
I have started this problem within B4R panel, but now my question is from B4A site.
I am receiving images (jpg) from Arduino camera unit and after data conditioning I am able to got a bitmap for farther evaluation.
Everything is done by this procedure:
B4X:
Dim out As OutputStream = File.OpenOutput(MyFolder, "Picture_" & i & ".jpg", False )   ' (or True)' depending from buffor content
out.WriteBytes(Buffer, 0, Buffer.Length)
out.Close
It means that I can have image only after storing a picture file.

Is it a way to use something like 'LoadBitmap' but directly from incoming stream or bytes array ?
I would like to not save an image as a file, hoping to receive them faster.

Kind regards
TomKluz
 
Last edited:

TomKluz

Active Member
Licensed User
Hello, Thanks for reply.

I am trying to do like this:

Byte input stream:
    Dim bb As B4XBytesBuilder
    Dim in As InputStream
    Dim bmp As Bitmap
    
    bb.Append(Buffer)
    'in.InitializeFromBytesArray(bb, 0, bb.Length)            ' Case 1
    in.InitializeFromBytesArray(Buffer, 0, Buffer.Length)  ' Case 2
    bmp.Initialize2(in)

In case 2 compilation is going on, but it is a case when Buffer contains only recently incoming data package.
Entire data (all partial data packages) should be in final bb which has to collect all of them but when I use a code like in Case 1
then compilation stops and I am getting this info:

Error.jpg


May I ask to point me what I am doing wrong ?
I was thinking that bb has to contain the same data type as Buffer.

Thank you in advance
TomKluz
 
Upvote 0

TomKluz

Active Member
Licensed User
Hello,
No Mr Erel, I am not using Prefix mode because I stiil use native Arduino in ESP32 Cam and I can't use it there till now.
On the other hand photos are coming in good condition (seems to be) and thay look lite this for example:
Picture_9.jpg

Once I have found that thay are coming in many pieces I have started to investigate where is the first one. In description of JPEG format I found, it is written that in the header of each jpg file there are always characters "JFIF". So, I am looking for them in this (probably prymitive) way:
Photo file:
Sub AStreams_NewData(Buffer() As Byte)
    
    'Dim in As InputStream
    'Dim bb As B4XBytesBuilder
    Msg = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
    
    If Msg.Length >= 10 Then
       MsgS = Msg.SubString2(6,10)
    End If   
    
        If MsgS = "JFIF" Then
                
            'bmp = in.InitializeFromBytesArray(bb, 0, bb.Length)       
            'bb.Clear       
            ImageView1.Bitmap = LoadBitmap(MyFolder,"Picture_" & (i-1) & ".jpg")
            Log ("Width  : " & bmp.Width)
            Log ("Height : " & bmp.Height)
                                                        
            'bb.Append(Buffer)
            Dim out As OutputStream = File.OpenOutput(MyFolder, "Picture_" & i & ".jpg", False)     'Starts to write a new file
            out.WriteBytes(Buffer, 0, Buffer.Length)
            out.Close
            i = i + 1
        Else
            'bb.Append(Buffer)
            Dim out As OutputStream = File.OpenOutput(MyFolder, "Picture_" & (i-1) & ".jpg", True)  'Adding data to already existing file
            out.WriteBytes(Buffer, 0, Buffer.Length)
            out.Close
        End If

End Sub

I would like to do the same with bb. After founding a header initialize bmp from bytes array and clean bb to collect next photo.
Unfortunatelly when I have tryed to do this I have got an error from B4A compiler.
What I have did wrong ? I don't know
With writeing to the file it is going fine. As you see it is possible to read 'With' and 'Heigh' with no problem. Next days I am going to try further analyse pixel by pixel.

Thank's in advance for your help
TomKluz
 
Upvote 0

TomKluz

Active Member
Licensed User
Obviusly I am writeing current buffer to the file constantly (as it is in my code) and I am getting several photos as files, but it is not my goal.
I am tending to achieve a current bmp and analyse colors pixel by pixel (bmp.GetPixel(x,y) as fast as possible in a loop. I was thinking that it possible to save some time
without saving data in between (maybe I am wrong). This is a real reason of my question.

Tell us which error do you see.
I can't see anything else apart info which I have placed 2 posts before. Compiler stops and show:
Error.jpg


I have nothing more. It is written that 'b4xBytesbuilder cannot be converted to byte'. I was thinking that bytes builder contains just bytes.
I am using this idea:

Dim bb As B4XBytesBuilder
Dim bmp As Bitmap
Dim in As InputStream
bmp.initialize2(in)

bb.Clear ' depends if it is a header or not
bb.Append(buffer)
bmp = in.InitializeFromBytesArray(bb, 0, bb.Length) ' bb must be fool

After last line compiler stops.

May I ask for some idea how to solve this ?

Kind regards
TK
 
Upvote 0

TomKluz

Active Member
Licensed User
Hello,
I am back after some break. Problem is solved. The reason of my previous questions was my little knowledge (no knowledge in fact) about B4XBytesBuilder. I was trying to compare bb to row bytes and in consequence above error has been displayed (Bytebuilder cannot be converted to bytes).
Recently I imagine bytebuilder as a box with some content. If someone wants to compare this content to something else, he should 'unpack' box content in specific way.
As soon as I start understand it in that way I have made discovery jpeg file start and stop characters in better way and also initialize bmp directly from byetbuilder (unpacked to the array of bytes). In fact difference of bmp initializaton from file and bytes array seems to be small (as Mr Erel said) but my satisfaction is great .

I am posting a code. Maybe someone can use it, maybe not but it works. Incoming bmp can be loaded or from file or from bytes array and evetually stored. Making a loop is possible and then a kind of movie goes on.

Byte builder used to check photo file:
Sub AStreams_NewData(Buffer() As Byte)
   
    bb.Append(Buffer)
   
    Dim startfile As Int = bb.IndexOf(Array As Byte(0xff,0xd8))  'begin of jpeg file in current buffer
    Dim endfile As Int = bb.IndexOf(Array As Byte(0xff,0xd9))    'end of jpeg file in current buffer
   
    If startfile = 0 And endfile = -1 Then      'this is some way to assemble jpg file from incoming byte packages
        filebilder.Clear
        filebilder.Append(bb.SubArray2(0, bb.Length))
    Else If startfile = -1 And endfile = -1 And filebilder.Length > 0 Then
        filebilder.Append(bb.SubArray(0))
    else if endfile > 0 And startfile > 0 Then
        filebilder.Append(bb.SubArray2(0,endfile+2))
               
        startbb = filebilder.IndexOf(Array As Byte(0xff,0xd8)) 'begin of jpeg file in destination bytebuilder
        endbb = filebilder.IndexOf(Array As Byte(0xff,0xd9))   'end of jpeg file in destination bytebuilder
       
        Store_Photofile
        Display_Photo
       
        lblView.Text = NumberFormat(((DateTime.Now - czaslast)/1000), 1, 3)
               
        filebilder.Clear
        filebilder.Append(bb.SubArray2(startfile, bb.Length))
           
    Else If startfile = -1 And endfile >= 0 And filebilder.Length > 0 Then
        filebilder.Append(bb.SubArray2(0, endfile + 2))
       
        Dim startbb As Int = filebilder.IndexOf(Array As Byte(0xff,0xd8)) '
        Dim endbb As Int = filebilder.IndexOf(Array As Byte(0xff,0xd9))
        Log("Startbb  " & startbb & "    Endbb  " & endbb & "    Rozmiar  " & filebilder.Length)

        Store_Photofile
        Display_Photo
       
        lblView.Text = i & "  " & NumberFormat(((DateTime.Now - czaslast)/1000),1,3)
           
        filebilder.clear
       
    End If
   
    bb.Clear
   
End Sub

Sub Display_Photo
    If startbb = 0 And endbb > 0 Then
        in.InitializeFromBytesArray(filebilder.SubArray( 0), 0, filebilder.Length)
        bmp.Initialize2(in)
        czaslast = DateTime.Now
        ImageView1.Bitmap = bmp
        'AStreams.Write("D3_Pho".GetBytes("UTF8"))
        stoper = DateTime.Now
        Do While DateTime.Now - stoper < 3
        Loop
        'bmp = LoadBitmap(MyFolder,"Picture_" & i & ".jpg")
    End If
End Sub
       
Sub Store_Photofile
        Dim out As OutputStream = File.OpenOutput(MyFolder, "Picture_" & i & ".jpg", False)
        out.WriteBytes(filebilder.SubArray(0), 0, filebilder.Length)
        out.Close
End Sub

Than you very much for your help.

TomKluz
 
Upvote 0
Top