Android Question Image Upload to Server Appears Corrupted

swabygw

Active Member
Licensed User
Longtime User
I have the following code in B4A to upload a single picture taken with the smartphone camera to the server (localhost IIS server on my PC):
B4X:
Dim fd As FileData
fd.Initialize
fd.Dir = Dir
fd.FileName = OrigFileName
fd.KeyName = "files"
fd.ContentType = "application/octet-stream"
files.Add(fd)
Dim NV AsMap
NV.Initialize
NV.Put("note1", "abc")
Dim req As OkHttpRequest
req = MultipartPost.CreatePostRequest("http://" & Starter.IPAddr & "/imgupload.aspx", NV, files)
hc.Execute(req, 1)
And on the server, in ASP:
B4X:
Dim length As Integer = Convert.ToInt32(Context.Request.InputStream.Length)
Dim buffer() As Byte = New Byte((length) - 1) {}
Context.Request.InputStream.Read(buffer, 0, length)
Dim ms As MemoryStream = New MemoryStream(buffer)
Dim fileAs New FileStream(Server.MapPath("test.jpg"), FileMode.Create, FileAccess.Write)
ms.WriteTo(file)
file.Close()
ms.Close
The problem is that, although an 18 kb file, correctly named "test.jpg", appears in the root folder of my server correctly, the file appears corrupted. For example, if I open it with MSPaint or Windows Viewer, both programs say the file is corrupted (and the preview in File Manager doesn't show the preview of the image). Any ideas as to what might be wrong?

P.S., Is there an easier way to upload an image file (potentially large file) from the phone to the server, without introducing additional setup/components like another server, B4J, etc.? My thinking is that sending bytes of data should work...
 
Last edited:

swabygw

Active Member
Licensed User
Longtime User
Btw, I've tried changing the ContentType to "image/jpeg" - same result.

I've converted the incoming data on the server to a string, and it shows the beginning of the data looks like this:

-----------------------------1461124740692\r\n
Content-Disposition: form-data; name=\"note1\"\r\n
\r\n
abc\r\n
-----------------------------1461124740692\r\n
Content-Disposition: form-data; name=\"files\"; filename=\"content://media/external/images/media/46\"\r\n
Content-Type: image/jpeg\r\n
\r\n
����\u0000\u0010JFIF\u0000\u0001\u0001\u0000\u0000\u
 
Last edited:
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Okay - does the B4X code look correct, at least?
you should use okhttputils2 and not the httpclient directly.

Example

B4X:
    Dim files As List
    files.Initialize
 
    ' File 1. Ein jpg
    Dim fd As MultipartFileData
    fd.Initialize
    fd.KeyName = "imagejpg"
    fd.Dir = File.DirAssets
    fd.FileName = "20141014_175713.jpg"
    fd.ContentType = "image/jpg"
    files.Add(fd)

    ' File 2. Ein png
    Dim fd As MultipartFileData
    fd.Initialize
    fd.KeyName = "imagepng"
    fd.Dir = File.DirAssets
    fd.FileName = "DonManfred.png"
    fd.ContentType = "image/png"
    files.Add(fd)

    ' File 3. Ein pdf
    Dim fd As MultipartFileData
    fd.Initialize
    fd.KeyName = "pdf"
    fd.Dir = File.DirAssets
    fd.FileName = "Ssykor101006-01PCMannes.pdf"
    fd.ContentType = "application/pdf"
    files.Add(fd)


    Dim job As HttpJob
    job.Initialize("Upload",Me)
    job.PostMultipart("http://domain.net/",CreateMap("action":"upload"),files)

I cant help on the server code as i dont know how to do it in asp
I just can say you need to treat the data as like data coming from a website formular with fileuploads...

Job.PostMultipart is just doing the same
 
Upvote 0

swabygw

Active Member
Licensed User
Longtime User
Thank you - this is an improvement. I'm now getting a positive Job.Success - before it was negative - so now I feel sure that the B4A side is right. I'll spend the weekend fighting with ASP to save the data correctly. :)
 
Upvote 0

swabygw

Active Member
Licensed User
Longtime User
Got it sorted out. For anyone else using ASP:

B4X:
Sub Page_Load(ByVal Sender As Object, ByVal e As EventArgs)

Dim objWriter As New System.IO.StreamWriter(Server.MapPath("UploadLog.txt"), True)
Try

objWriter.WriteLine("Request.Files.Count: " & Request.Files.Count.ToString)
'If Request.Files.Count > 0 Then
'  objWriter.WriteLine("File: "  & Server.HtmlEncode(Request.Files.AllKeys(0)))
'  objWriter.WriteLine("  size = "  & Request.Files(0).ContentLength.ToString)
'  objWriter.WriteLine("  content type = " & Request.Files(0).ContentType.ToString)
'  objWriter.WriteLine("  ext = "  & System.IO.Path.GetExtension(Request.Files(0).FileName))
'End If

For x = 0 To Request.Files.Count-1
   Dim s As String = Server.HtmlEncode(Request.Files.AllKeys(x))
   Dim f As HttpPostedFile = Request.Files(s)
   Dim fname as String = s '"test.jpg"
   objWriter.WriteLine("New Filename: " & s)
   f.SaveAs(Server.MapPath(fname))
Next

Catch ex as Exception
objWriter.WriteLine(ex.Message)

Finally
  objWriter.Close

End Try

End Sub
 
Upvote 0
Top