Trying to do on the canvas-e uploader images.
The conditions are as follows:

  1. There should be three picture selection buttons (Browse) (Max. 3 photos).
  2. When a picture is selected, base64 is generated and substituted into hidden input.
  3. After that, when submitting the form, we send base64 to the script.

The problem is that I do not know how to properly implement.

Form Code:

<form enctype="multipart/form-data" method="post" action="upload.php"> <label for="fileToUpload">Select Files to Upload</label> <input type="text" name="photo[]" id="hiddenInput0" value=""> <input type="text" name="photo[]" id="hiddenInput1" value=""> <input type="text" name="photo[]" id="hiddenInput2" value=""> <input type="file" name="filesToUpload[]" id="filesToUpload0" accept="image/*"> <input type="file" name="filesToUpload[]" id="filesToUpload1" accept='image/*'> <input type="file" name="filesToUpload[]" id="filesToUpload2" accept='image/*' /> <input type="submit" value="Upload" /> </form> 

A script that gets values ​​from #filesToUpload0 :

 if (window.File && window.FileReader && window.FileList && window.Blob) { document.getElementById('filesToUpload' + 0).onchange = function() { var files = document.getElementById('filesToUpload' + 0).files; for (var i = 0; i < files.length; i++) { resizeAndUpload(files[i], i); } }; } else { alert('The File APIs are not fully supported in this browser.'); } 

The fact is that I cannot send functions to the #filesToUpload1 and #filesToUpload2 .

Those. I need to send three values, from each Browse to this script, which receives them and inserts images into the hidden input base64.

 function resizeAndUpload(file, num) { var reader = new FileReader(); reader.onloadend = function() { var tempImg = new Image(); tempImg.src = reader.result; tempImg.onload = function() { var MAX_WIDTH = 640; var MAX_HEIGHT = 480; var tempW = tempImg.width; var tempH = tempImg.height; if (tempW > tempH) { if (tempW > MAX_WIDTH) { tempH *= MAX_WIDTH / tempW; tempW = MAX_WIDTH; } } else { if (tempH > MAX_HEIGHT) { tempW *= MAX_HEIGHT / tempH; tempH = MAX_HEIGHT; } } var canvas = document.createElement('canvas'); canvas.width = tempW; canvas.height = tempH; var ctx = canvas.getContext("2d"); ctx.drawImage(this, 0, 0, tempW, tempH); var dataURL = canvas.toDataURL("image/jpeg"); $("#hiddenInput" + num).val(dataURL); //тут вставляем значение в скрытый input } } reader.readAsDataURL(file); } 

I understand what I've done here, but I try to make it as simple and correct as possible. And do not substitute crutches, and then "it works, it does not."

The idea is that the user enters the page, fills out a form.
At the end of the form, he attaches a maximum of 3 images and sends the form to the PHP processing script.

I want to use canvas, because the photos are from 2 to 3 megabytes, and it just reduces them on the client side, which is what I need.

I also want to ask: how does this code work in terms of security?
Do you need any checks in PHP processing to avoid anything extra?

    1 answer 1

    In .files #filesToUpload0 there is only one file selected in this <input> . Hang up the change event handler is needed for all 3 <input> -a:

     if (window.File && window.FileReader && window.FileList && window.Blob) { $(".file").on("change", function() { if (this.files.length != 0) { resizeAndUpload(this.files[0], $(this).data("id")); } }); } else { alert('The File APIs are not fully supported in this browser.'); } function resizeAndUpload(file, num) { var reader = new FileReader(); reader.onloadend = function() { var tempImg = new Image(); tempImg.src = reader.result; tempImg.onload = function() { var MAX_WIDTH = 640; var MAX_HEIGHT = 480; var tempW = tempImg.width; var tempH = tempImg.height; if (tempW > tempH) { if (tempW > MAX_WIDTH) { tempH *= MAX_WIDTH / tempW; tempW = MAX_WIDTH; } } else { if (tempH > MAX_HEIGHT) { tempW *= MAX_HEIGHT / tempH; tempH = MAX_HEIGHT; } } var canvas = document.createElement('canvas'); canvas.width = tempW; canvas.height = tempH; var ctx = canvas.getContext("2d"); ctx.drawImage(this, 0, 0, tempW, tempH); var dataURL = canvas.toDataURL("image/jpeg"); $("#hiddenInput" + num).val(dataURL); } } reader.readAsDataURL(file); } 
     input { display: block; } 
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <form enctype="multipart/form-data" method="post" action="upload.php"> <label for="fileToUpload">Select Files to Upload</label> <input type="text" name="photo[]" id="hiddenInput0" value="" /> <input type="text" name="photo[]" id="hiddenInput1" value="" /> <input type="text" name="photo[]" id="hiddenInput2" value="" /> <input type="file" class="file" data-id="0" accept="image/*" /> <input type="file" class="file" data-id="1" accept='image/*' /> <input type="file" class="file" data-id="2" accept='image/*' /> <input type="submit" value="Upload" /> </form> 

    I did not refactor the resizeAndUpload function.
    With <input type="file"> I removed the name so that the pictures themselves would not go to the server. If you need both the pictures themselves and their copy in base64, then the name needs to be returned.

    On the server side it is necessary to check incoming data. Checks on the client (browser in this case) are made for the convenience of the client. Checks on the server - for security.

    • Thank ! Do I do it right? what is hiding base64 in input and then sending them to the server along with the form? Concerning security, I found a couple of methods for how to validate base64 for image detection. True, I don’t know which way is better, but I’ll still have to look for a simpler and more reliable method of server side validation. - user199432 7:55 pm
    • @StackOverFollow "correctly" is a relative concept. If in terms of performance, it should work. In terms of optimizing the amount of data transferred, I don’t remember how files are transferred to HTTP by default. If in binary form, then base64 will lose in this regard. Hidden <input> s are not a kind of crutch, especially if the form is not sent by Ajax. - Regent
    • Well, by the word correctly, I meant, does not violate the very logic of the work - at all levels - as I understood it is not, and that is good. I just needed the simplest code, since there are many options on the network, but there are rewards with a lot of excess. Thank you for help ! - user199432