JSON SQL image field to byte array

Ian Garton

Member
Licensed User
Longtime User
Hi

I'm storing png, jpeg files in an SQL Server database using IMAGE fields.
My b4a app is downloading these using a asp.net JSON web service.
The b4a JSONParser library returns the image field as a comma separated int value string, rather than a hex string.

I can't figure out a method for converting this to a byte array, and thus to a bitmap object, or write as a file.

JSON String from Web Service:
[{"Attachment":[255,216,255,224,0,16,74,70,73,70,0,1,1,0,0,1,0,1,0,0,255,219,0,67...............],"Filename":"Photo.jpg"}]

...
AttachmentString = Row.Get("Attachment")

AttachmentString =
[255,216,255,224,0,16,74,70,73,70,0,1,1,0,0,1,0,1,0,0,255,219,0,67...............]

How do I convert AttachmentString in to a byte array?
 

Ian Garton

Member
Licensed User
Longtime User
That Erel for the response.

However I feel that running a loop through the comma separated byte values would be extremely cpu intensive and slow.

Perhaps I need to come up with something better on the web service end.
 
Upvote 0

Ian Garton

Member
Licensed User
Longtime User
Ok, so I've created the following code, however BitConverter seems to give totally incorrect values.

Is there a way of determining the size for the array? It doesn't seem good practice to do what I've done.

Or am I totally on the wrong track here....

B4X:
    Dim Attachment As String
      Attachment = Row.Get("Attachment")   ' Extract JSON image field as string
      Attachment = Attachment.SubString2(1, Attachment.Length-1)  ' Remove [ and ] chars
      
      Dim Vals(132000) As Int
      Dim i As Int
      i = 0   ' Array position
      Do While Attachment.Contains(",")   ' Extract int for each comma value in string
         Vals(i) = Attachment.SubString2(0, Attachment.IndexOf(","))
         Attachment = Attachment.SubString(Attachment.IndexOf(",") + 1)
         i = i + 1
      Loop
      ' Include final value
      Vals(i) = Attachment
      
      ' Convert ints to bytes      
      Dim b As ByteConverter 
      Dim Buffer() As Byte
      Buffer = b.IntsToBytes(Vals)
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
This code works:
B4X:
Sub Activity_Click
   Log(1)
   Dim j As JSONParser
   j.Initialize(File.ReadString(File.DirAssets, "json.txt"))
   Dim l As List
   l = j.NextArray
   Dim m As Map
   m = l.Get(0)
   Log(2)
   Dim bytesList As List
   bytesList = m.Get("Attachment")
   Dim bytes(bytesList.Size) As Byte
   For i = 0 To bytes.Length - 1
      bytes(i) = bytesList.Get(i)
   Next
   Log(3)
   Dim bmp As Bitmap
   Dim in As InputStream
   in.InitializeFromBytesArray(bytes, 0, bytes.Length)
   bmp.Initialize2(in)
   Activity.SetBackgroundImage(bmp)
End Sub

However your image size is about 400k. You should try to compress the original image.
It will work much better with a better compressed image.
 
Upvote 0

Kwame Twum

Active Member
Licensed User
Longtime User
Hi guys, I used the code above with a query similar to
B4X:
"SELECT img FROM Table_1 WHERE id = 'PPP'" 'img contains the bytes of the image
However, I get the an error in the LogCat during the initializing stage. >> bmp.intialize2(in)
Message:Error loading bitmap.

Logs....
B4X:
java.lang.RuntimeException: Error loading bitmap.
    at anywheresoftware.b4a.objects.drawable.CanvasWrapper$BitmapWrapper.Initialize2(CanvasWrapper.java:521)
    at com.madflow.eazy_chat.chattz._jobdone(chattz.java:740)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:170)
    at anywheresoftware.b4a.keywords.Common$5.run(Common.java:958)
    at android.os.Handler.handleCallback(Handler.java:587)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:138)
    at android.app.ActivityThread.main(ActivityThread.java:3701)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)
    at dalvik.system.NativeStart.main(Native Method)

I thought the image size could be a factor, but I've tried working with much smaller images, and it still gives the same error.:(
Any help is much appreciated :)
 
Upvote 0

Kwame Twum

Active Member
Licensed User
Longtime User
Erel, I used the StringUtils' EncodeBase64 member to encode the image before storing it in the database. Could that be the issue for not storing the image correctly?
Try this url: Select Query
That was after inserting the encoded image. Could it be incorrectly stored?
Really confused here...o_O
 
Upvote 0
Top