I'm writing an application in HTML5 + JS, and at some point I need to upload the contents of a <canvas>
element, which has some PNG file drawn on it. So I'm doing:
$('#img').val(canvasElement.toDataURL());
As You can see, I provide no arguments to toDataURL function, so the extracted image will be in PNG format. #img
is a text input (with name attribute "img") that is used later to upload base64 representation of the image, extracted from canvas, to the server. I do it with AJAX, requesting a PHP file which contains the code below:
$data = explode(',', $_POST['img']);
$imgdata = base64_decode($data[1]);
$ifp = fopen('superGraphicFile.png', "wb");
fwrite($ifp, $imgdata);
fclose($ifp);
That works, but unfortunately 300x600 PNG file is enough to make AJAX request last really long (like 20 seconds), because the file size is around 400 kB then. The amount of time needed is unacceptable in my case.
I was wondering about how to reduce the amount of data sent to the server and I thought that sending it as JPG would be cool, as we can specify the quality of the JPEG image extracted from canvas. For example, calling toDataURL('image/jpeg',0.7)
, makes the file over 10 times smaller than calling it with no arguments. However, I have to preserve information about transparency from the original PNG file, and since JPG can't do it, I would like to invent some way to recreate the original PNG on the server side.
At first, I thought about filling all the transparent pixels from the original PNG with some specific color, convert it to JPG, send to the server, and replace all pixels having that color with transparent pixels. This, however, would probably not work, because I also need to preserve semi-transparent pixels from the original image. Maybe there is some method to extract the alpha channel from original image, send it to the server as another JPG and apply it as a mask on the server side, recreating the original PNG that way? Or maybe I'm missing some other solution?
I thank You in advance for all Your advices.
EDIT: The 20 seconds I write about might have been some problems with my internet connection, because I didn't change anything and now it takes around a second to transfer 400 kb of data. But I still think, that saving server resources by ten and making an app work faster would be a cool thing to do.