3

My App involves heavy client side image manipulation. Since the files are modified so frequently during a users session we do not physically upload them to the server until the user is finished and chooses to save the image(s).

The images are read from the client using the html5 file API and stored in memory as base64 strings where the user proceeds to perform his/her manipulations quickly and efficiently.

When the user chooses to save we transfer the string or strings to the server via a standard ajax POST and then build the image into a physical file server-side.

What I would like to do is provide a progress bar for this final upload stage.

Now, I am well aware that the html5 spec includes support for file upload progress reporting. However we are not using the standard upload methods, instead, as mentioned above the images are sent as strings.

So my question really boils down to the following:

A) Is there anyway to actual measure the actual bytes sent during a simple post (PHP serverside). If so this would work as I already have the image size in bytes from the HTML5 filereader api.

B) If not is there anyway I can convert the base64 data into actual files on the fly and send them via the standard html5 upload method, reporting the progress as we go.

In either case... If so, how?

Many thanks in advance.

gordyr
  • 5,618
  • 13
  • 51
  • 118

2 Answers2

2

It's easier when you send the Base64 image via ajax. Ajax works with a callback function, so just use an indicator of some sort to let the user know that ajax has been initiated (i.e. the file download has started ). On completion the callback function will run, now you can turn off the indicator whatever it might be.

As far as measuring actual bytes, via ajax I'm not sure.

This method

showing progressbar progress with ajax request

suggest estimating it. I would take it a step further and maybe time how long it take the callback over say 10 tries( use this average to estimate your progress bar and also use the 90% trick mentioned above ).

Or if you want to encode/decode your Base64 text.

How can you encode a string to Base64 in JavaScript?

Community
  • 1
  • 1
  • Yep, right now we are simply showing a simple ajax spinner. Which is acceptable on decent cable/fire optic connections, but with 2048x2048 rez images on slower connections it simply isn't enough feedback to the user. I'll look into estimation options though. Thanks. :) – gordyr Dec 17 '12 at 19:22
  • The other answers suggest periodically ajaxing the server to get a status of the "job" - http://stackoverflow.com/questions/3829708/setting-up-ajax-progress-bar. However I'm not sure how you can get an indication of how much of the Base64 Text has hit the server. If you know how to do this, than that would be another way. –  Dec 17 '12 at 19:29
  • thanks pure_code, this is basically javascript long polling, which allow will work is something I would ideally like to avoid as we don't want the extra http requests. I should have mentioned it in my original question, my apologies. Thanks anyway! – gordyr Dec 17 '12 at 19:33
  • I think the main bottleneck would be the network and the server. I imagine the client sends the image wrather quickly, so I would guess that you need feedback from the server if you want to give the user an indicator of time left, if you don't want to pay for the cost of hitting the server, estimation might be your best bet. –  Dec 17 '12 at 19:34
  • But I don't think you can get progress just from the client as it does not know what happens to the data it sends out in to the network –  Dec 17 '12 at 19:48
  • Indeed. Which after more investigation the only option is to somehow convert base64 imagedata into a binary file clientside, then use the html5 upload api to report progress. The trouble is... How do I convert base64 into a binary file. – gordyr Dec 17 '12 at 19:51
  • http://stackoverflow.com/questions/246801/how-can-you-encode-to-base64-using-javascript –  Dec 17 '12 at 19:59
  • If that's how you want to do it...answer above provides a way to do conversions.... –  Dec 17 '12 at 20:00
  • Is there anything else you needed?..hint...hint. –  Dec 17 '12 at 20:00
  • You sir... are a legend. :-) This is exactly what I needed! If you want to add the link in the comments into your actual answer I will mark it as correct. Huge props to you pure_code, you just made my day! Cheers! – gordyr Dec 17 '12 at 20:03
1

Depending on the server technology you are using, there are several options.

  1. Use Comet or Javascript long polling to get the progress of the upload from the server, and update the progress bar from the client side

  2. If you are using .Net technologies in the backend, explore the SignalR library, which will provide all the plumbing to provide real time communication between the server and the client.

Jon Adams
  • 22,969
  • 17
  • 78
  • 115
Scorpion-Prince
  • 3,326
  • 2
  • 16
  • 24
  • Comet looks interesting, i'll look into it further. I'd like to avoid long polling if possible due to the extra requests, but it is certainly still an option. Ideally I am looking for a client side solution which will allow me to take advantage of the html5 file upload method. (This app only needs to support html5 browsers thankfully) – gordyr Dec 17 '12 at 19:26
  • Got it.. if you need to support only HTML5 browsers, look at [this](http://tutorialzine.com/2011/09/html5-file-upload-jquery-php/) article. [Here](http://www.freshdesignweb.com/jquery-html5-file-upload.html) is a list of jQuery plug-ins which allow upload with progress. – Scorpion-Prince Dec 17 '12 at 19:31
  • Thanks Scorpion-Prince. This is very useful. Although the problem remains in that I am dealing with base64 imagedata rather than a binary file read from the filereader api. The reason for this is due to the heavy manupilation meaning that we need to constantly manipulate images on a canvas element. If I could somehow convert the image from the final base64 data back into a binary file I could easily use this method as an elegant solution. We are definitely on the right track. cheers. – gordyr Dec 17 '12 at 19:38
  • @gordy1, I found [this](http://blog.danguer.com/2011/10/24/base64-binary-decoding-in-javascript/) blog which talks about converting from Base64 to a Byte Array. [Here](http://blog.calyptus.eu/seb/2009/05/png-parser-in-javascript/) is another one, which converts Base64 to the PNG format. HTH. – Scorpion-Prince Dec 17 '12 at 20:29
  • Thanks mate. Between the links you and pure_code have provided I have managed to solve the issue. It works beautifully and elegantly. Many thanks for all your help. I wish I could award the answer to both of you. – gordyr Dec 17 '12 at 21:02