Android Question Error converting byte array to image - Runtime Error Loading Bitmap

adrianfreitas

Member
Licensed User
Longtime User
Hello people. I am rewriting code that gets MPEG from IP cameras, displaying quietly at up to 25 fps. I found the code in a VB6 forum and it comes almost literally implement a solution described in this post, in which the user did not provide a practical example, but described the structure used.
My translation is perfectly following the debugging results of the original code, but it generates an error in the process of converting the string to bitmap.
I try to convert the string to bytes and then to image (Erel code snippet) but the error happens:

Error occurred on line: 114 (main)
java.lang.RuntimeException: Error loading bitmap.
at anywheresoftware.b4a.objects.drawable.CanvasWrapper$BitmapWrapper.Initialize2(CanvasWrapper.java:521)
at com.vs.projmpeg.main._bytestoimage(main.java:416)
at com.vs.projmpeg.main._oastreams_newdata(main.java:519)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:636)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:305)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:238)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:121)
at anywheresoftware.b4a.BA$3.run(BA.java:332)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)
at dalvik.system.NativeStart.main(Native Method)

Below I will leave my code and attach the file with the project
 

Attachments

  • Proj MJPEG v2.zip
    227.8 KB · Views: 203

adrianfreitas

Member
Licensed User
Longtime User
B4X:
Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("wMain")
    oSFcn.Initialize
    oSck.Initialize("oSock")
    oSBT.Initialize
    'socket.RemoteHost = "plazacam.studentaffairs.duke.edu"
    oTmr.Initialize("oTmer", 500)
    oTmr.Enabled = True
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub

Sub oTmer_Tick
    If oSck.Connected = False Then ConnectSocket
End Sub

Sub ConnectSocket
    'oSck.Connect("96.249.39.25", 80, 3000)
    oSck.Connect("195.113.207.238", 80, 3000)
End Sub
Sub oSock_Connected(Successful As Boolean)
    If Successful Then
        oAStreams.Initialize(oSck.InputStream, oSck.OutputStream, "oAStreams")
        Dim byBuffer() As Byte, sTmp As String
'        sTmp = "GET /axis-cgi/mjpg/video.cgi?resolution=640x480&dummy=1480384795175 HTTP/1.1" & _
'            Chr(10) & Chr(13) & "Host: 96.249.39.25" & Chr(10) & Chr(13) & _
'            "Connection: keep-alive" & Chr(10) & Chr(13) & Chr(10) & Chr(13)
        sTmp = "GET /mjpg/video.mjpg HTTP/1.1" & Chr(13) & Chr(10) & "Host: 195.113.207.238" & _
            Chr(13) & Chr(10) & "Connection: keep-alive" & Chr(13) & Chr(10) & Chr(13) & Chr(10)
        byBuffer = sTmp.GetBytes("UTF8")
        oAStreams.Write(byBuffer)
    End If
End Sub

Sub oAStreams_NewData (Buffer() As Byte)
    oSBT.Append(BytesToString(Buffer, 0, Buffer.Length, "UTF8"))
    dd = oSBT.ToString
    If ContentLength = 0 Then
        i1 = oSFcn.InString(dd, "Content-Length: ")
        If i1 > 0 Then                              ' Remove the MPEG header and get file length
            Dim sTp As String
            i1 = i1 + 16
            sTp = oSFcn.MidS(dd, i1)
            i2 = oSFcn.InString(sTp, Chr(13) & Chr(10) & Chr(13) & Chr(10))
            If i2 > 0 Then
                ContentLength = oSFcn.Mid(dd, i1, i2 + 1)
                dd = oSFcn.MidS(dd, i2 + 4)
            End If
        End If
    End If
    If ContentLength > 0 AND oSFcn.Len(dd) >= ContentLength Then  'Get JPEG content, convert to image and show
        Log(ContentLength)                      
        Log(oSFcn.Len(dd))
        ByteArray = dd.GetBytes("UTF8")           ' In original code, ByteArray Langht = String lenght      
        Log(ByteArray.Length)                     ' Here, ByteArray lenght is almost x2
        dd = oSFcn.MidS(dd, ContentLength)
        ContentLength = 0
        oSBT.Initialize
        ivVideo1.Bitmap = BytesToImage(ByteArray)
        DoEvents
    End If
End Sub
Sub oAStreams_Error
    ToastMessageShow(LastException.Message, True)
    Log(LastException.Message)
End Sub
Sub oAStreams_Terminated
    Log("AStreams_Terminated")
End Sub

Public Sub BytesToImage(bytes() As Byte) As Bitmap
   Dim In As InputStream
   Log(bytes.Length)
   In.InitializeFromBytesArray(bytes, 0, bytes.Length - 1)
   Dim bmp As Bitmap
   bmp.Initialize2(In)                           ' <<< Here occurs the error
   Return bmp
End Sub
 
Upvote 0

adrianfreitas

Member
Licensed User
Longtime User
Thank you for your answer, Erel.
What is the correct way to do it then, since I need to use the string manipulation to remove the MPEG header, take the JPEG and display it .... just like the user 'goldmagnet in that post (https://www.b4x.com/android/forum/threads/mjpeg-decoder-artitecture.32756/page-3):
There is no secret, just use the TCP Streams to connect to the device and fill a buffer with data. Then when time allows (when you are not receiving data) parse the buffer reading M JPEG headers and extract the JPEG data and display, then delete this data from the buffer. Thats it really.

Could someone help please?
 
Upvote 0

adrianfreitas

Member
Licensed User
Longtime User
Sorry I did not understand ... the data is a received from IP Cam via the socket, and the project posted is accessing a public camera that works 24hs delivering an MPEG at 15 fps. I found the goldmagnet post in which it implements this solution, but it does not provide an example, it only describes how it did it, and I also found a code in VB6 where the same approach was used and works very well. After many attempts the code above is as close as I could get. I need the help of someone more experienced in B4A.
 
Upvote 0

adrianfreitas

Member
Licensed User
Longtime User
Thank you very much!! I just translated the code to Xojo and .Net today and in both it worked 100% but I can't figure out how to make it in B4A. So I'll wait for your help.
 
Upvote 0
Top