Uploading jpgs as bytestream

ostau

Member
Licensed User
Longtime User
Hallo Erel,


I would like to ask you for an advice how to handle the following task:

I have to create a solution pn an Andoid tablet for nursing purposes.
The nurse should describe a wound and should be able to take up to 6 photos.
The wound description and the photos should be uploaded to a MS SQL Server by pressing a button.

I have created an app, which makes all on the tablet side, whch means, I have the infos in an array and up to 6 pictures as jpg on the local device.

On the server, I use BV.NET and I have created some serverices, which accept other incoming data.
Now my question: do you think it´s better to upload the files to the server and run a (e.g. COM-)service on the server, which moves the jpg´s into the database or
is it possible to upload the jpgs as a byte-array directly in the post-parameter (which I would prefer!, becuase hte service would be much easier to create and no problem with write and read permissions and all that stuff). If yes, how can I transform my local jpgs into a serialized string (I didn´t find a lib for that), which can then be read on server side and then be stored in the BLOB oft he SQL Server?


Could you please help me?

Thanks in advance, Oskar
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0

ostau

Member
Licensed User
Longtime User
Short description how to transfer a jpg from Android to a .NET-Service using POST

Hi there,
just in case one do have the same task, here is a quick description to achive a result.

Open the file and fetch it into a CharArray
Transform it to a byte Array
transform it into a URL-Safe base64 encoded string
put the parameter name of the Webservice as plain text & "=" , join the string and use it as parameter for webservice.InitializePost2 (this will transform the string to an UTF-8 Byte array

start the webservice. On the .NET side it will appear as string.

in the webService
Create a standard base64 string (undo the URLSAFE transcription (replace all - by + and all _ by /).
transform the string into a byte array
transform the byte array into a memory stream
create a image from the memory stream

save the image as file

if you want to store the jpg in a database, you first have to transofrm it into a byte array.

Sound complex and indeed, it is. It took me some hours to find this way.

Here the main steps as code snippets:

sb.Append ("Pic=") 'Name of the WebServiceParameter

Dim in As InputStream
Dim out As OutputStream

in = File.OpenInput(PicturePath, PictureName)
out.InitializeToBytesArray(0)
File.Copy2(in, out)

Dim data() As Byte
data = out.ToBytesArray

Dim b64 As Base64
b64.BreakLines = True
b64.UrlSafe = True
b64.LineLength = 75

Dim str64Pic As String
str64Pic = b64.EncodeBtoS(data,0,data.Length)
sb.Append(str64Pic) 'Append the urlsafe base64 coded string
...

---- WebService
request.InitializePost2(URL,conv.StringToBytes(sb.tostring,"UTF-8"))
...
...


---- At the .NET side

Dim r As Byte() = Convert.FromBase64String(StringBase64.Replace("-", "+").Replace("_", "/")) 'Bild in Originalgröße als Bytestream
Dim ms As New MemoryStream(r)
Dim img As Image = Image.FromStream(ms)

Dim rOut As Byte()
Dim imgOut As Image
Dim msOut As New MemoryStream()

imgOut = img.GetThumbnailImage(1024, 768, myCallback, IntPtr.Zero)
imgOut.Save(msOut, System.Drawing.Imaging.ImageFormat.Jpeg)
rOut = msOut.ToArray()

rNewWundePosBild.Bild = rOut 'Update database
 
Upvote 0

ssmacwilliams

New Member
Licensed User
Longtime User
Help me expedite a similar solution

Good morning Oskar
Thank you for quick description.

I am working on a similar app... basically proof of concept. I was origingally looking to store the images into MSSQL server, but thought of the size of the database after a 6 months would be monsterous.

Had you thought of storing the link? IF so, what methods of transport did you pursue to move the image off the device and onto the server?

I am fairly new to the Android programming environment, but thought that maybe SQLLite might of had an xcopy function or something.

How is your current implementation working for you?

Thanks in advance for your advice and tutorage.
Steve
 
Upvote 0

ostau

Member
Licensed User
Longtime User
Transfer data

Hallo Steve,

sorry for the delay, I´m not every day in the forum.

To transfer the data from the device to a windows based server, you can use the way I described above. Due to security reasons I have to store the img as bytestream in the database (the link could be broken, if a user deletes the file by accident). My custumers mainly work with MSSQL standard or enterprise, so database size is not an issue.

If you can use a soap service, the transfer is easier, because you must not make the bytestream URLsafe.
I didn´t find a simple way to call a soap service from basic2android, so I decided to transfer the data via a POST parameter. The problem here ist, that in the post-parameter no / and no + are allowed (the service misinterpretes it and the transfer fails) - so the only way is to make the bytestream URLSafe..

If you don´t want to store the bytestream in the database just store the picture as file: in .NET use

Dim ms As MemoryStream = New MemoryStream(r)
Dim img As Image = Image.FromStream(ms)
img.Save("D:\test.jpg")

where r is the decoded bytestream from the device.

The codesnippet to save the bytestream from the POST-Parameter into the SQL-Server is:

Dim rNewWundePosBild As dsPMDS.WundePosBilderRow = dsPMDSUpdate.WundePosBilder.NewRow()

Dim myCallback As New Image.GetThumbnailImageAbort(AddressOf ThumbnailCallback)

'undo UTLSafe and decode from Base64
Dim r As Byte() = Convert.FromBase64String(StringBase64.Replace("-", "+").Replace("_", "/"))
Dim ms As New MemoryStream(r)
Dim img As Image = Image.FromStream(ms)

Dim rOut As Byte()
Dim imgOut As Image
Dim msOut As New MemoryStream()

'reduce the size
imgOut = img.GetThumbnailImage(1024, 768, myCallback, IntPtr.Zero)
imgOut.Save(msOut, System.Drawing.Imaging.ImageFormat.Jpeg)
rOut = msOut.ToArray()
<YourNewDataRow>.<ColumnName> = rOut

....
 
Upvote 0

ssmacwilliams

New Member
Licensed User
Longtime User
Transfer data

Thanks ostau for your reply.
I will have to dig deeper into your solution. What I ended up doing was separating the data from the image data. Using the HttpUtils, I passed the client information to the MSSQL server along with the image name (a concatentation of variables) then FTP'd the image up to a specific location that would later be opened via Sharepoint. The solutions works full cycle.

My concern is 3 fold.
1) Performance of queries should I store the images in the database.
2) Security ~ obviously
3) Ignorance of the bytestream input/output
a. I had originally tried the bytestream and was able to input data into the table... provided it was Nvarchar/varchar. but was unable to "recompile" it back out into an aspx.

Really not sure how secure is secure.
 
Upvote 0
Top