Maxlight Maxlight - 1 month ago 15
PHP Question

how to send image from canvas using toDataURL to php

I have this code

<form id="memeForm" method="post">
{{ csrf_field() }}
<div class="col-centered" style="padding-top:15px;">
<canvas id="canvas" width="{{$meme->width}}" height="{{$meme->height}}" style="border:0px solid white"></canvas>
</div>
<input name="meme" id="meme">
<div class="image">
<img id="originalmeme" src="{{ url('memes/'.$meme->slug .'.'. $meme->extension) }}" style="display: none;" class="img-responsive center-block">
</div>
</form>


and I want to save canvas as image and send it to my php code

$("#saveMeme").on("click", function(e){
var canvasImageData = canvas.toDataURL({
format: 'jpeg',
quality: 1
});
$('#meme').val(canvasImageData);

console.log('meme: '+$('#meme').val());

e.preventDefault();
$('#memeForm').attr('action', "/uploadmeme.php").submit();
});


Since I am using an input with id 'meme' to store image data, won't this be a problem since input max value is 521kb, according to this post: Why is the default max length for an input 524288?

I've noticed that in chrome image generated from Canvas has different code then one in Firefox. Can I send the image some other way?

pid pid
Answer

I don't think there is a different way to send an image extracted from a canvas. Chrome and Firefox have different codes because if you look closely you'll discover that the canvas rendering is slightly different. They don't use exactly the same algorithms to render, so a tiny difference may cause effects like anti-aliasing, dithering and similar that have 1 or 2 bits different -- enough to generate a completely different code because JPG uses specific algorithms that are affected by every single pixel (colorspace optimizations and such).

The problem with the field limit is easy to avoid. Just split the string at every 512Kb, then count how many fragments you have and finally create the DOM nodes inside the form:

var i, node, fragments;

// imagine "fragments" to be the array of the splitted dataURL
fragments = [ "gjwoituwe...", "4r1njhjfrqwf...", "e123jeiod..." ];

for (i = 0; i < fragments.length; i++)
{
  node = $("<input type='hidden' name='fragment_" + i + "'>").val(fragments[i]);
  $("#memeForm").appendChild(node);
}

You'll receive those fragments as:

$_POST['fragment_0']
$_POST['fragment_1']
$_POST['fragment_2']
...

You can now put those fragments together on the server to obtain the full dataURL.

You should remove the static #meme field at that point and fix the rest of the code.

Comments