问题
I am trying to get work my code, but I have not been successful. Basically what I want is to apply a resize algorithm to multiple images selected by the user, making them in HTML5 Canvas and then inserting each string (DataURL) in the input array to be sent by via POST method.
My code (CLIENT) index.html:
<html>
<head>
</head>
<body>
<input type="file" id="pictures" multiple><br>
<form id="frm" action="save.php" method="POST">
<input type="hidden" name="sizedpics[]" id="sizedpics">
<button type="button" onclick="resize()">submit!</button>
</form>
<canvas style="display:none;" id="canvas" width="800"></canvas><br>
<script>
var pics=[];
function resize()
{
var numpictures=pictures.files.length;
var compresion=0.5;
var dataurl;
for (i=0;i<numpictures;i++)
{
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
img = new Image();
img.onload = function ()
{
canvas.height = canvas.width * (img.height / img.width);
/// step 1
var oc = document.createElement('canvas'), octx = oc.getContext('2d');
oc.width = img.width * compresion;
oc.height = img.height * compresion;
octx.drawImage(img, 0, 0, oc.width, oc.height);
/// step 2
octx.drawImage(oc, 0, 0, oc.width * compresion, oc.height * compresion);
ctx.drawImage(oc, 0, 0, oc.width * compresion, oc.height * compresion, 0, 0, canvas.width, canvas.height);
// Step 3
dataurl = canvas.toDataURL("image/jpeg");
pics.push(dataurl);
}
img.src = window.URL.createObjectURL(pictures.files[i]);
}
document.getElementById("sizedpics").value=pics;
document.forms["frm"].submit();
}
</script>
</body>
</html>
My code (SERVER) save.php
<?php
print_r(count($_POST['sizedpics']));exit();
?>
I think there is a problem of sync with the javascript, but I don't know how to solve it, I need to send all images (base64 encoded DataURL strings) to my server using a single input "sizedpics".
Some of you know where the error? Thanks for reading, and please excuse my horrible way to write English :-)
回答1:
EDIT: Updated comments in answer and updated code.
There were a number of things that stopped your code from working, alas I'm tired and forgot to make note of them as I went and have forgotten the specifics. :(
You may wish to review the following code.
It loads the images using a fileReader and the method .readAsDataURL
. This then fires a user-supplied callback on completion. This callback method then attempts to load the dataURL as an image. When (if!) this succeeds, the image is drawn onto a scaled canvas and then the dataURL of that canvas is retrieved. This dataURL is added to an array and the number of scaled images is compared to the number of selected images. When the two numbers match, it JSON encodes the array and stuffs it into the hidden input, before submitting the form.
On the php side, we get the submitted data and JSON decode it. We then display a count of the number of images in this array, before ouputing each element as the src of an image,to confirm successful upload.
I've added code that will ensure the chosed file is an image before processing it any further. You can select a mixed list of files and only the images will be processed. I don't handle the case when the chosen file is an image yet trying to load it into an img element fails.
resizeAndUpload.html
<html>
<head>
<script>
function newEl(tagName){return document.createElement(tagName);}
var nFiles, nSized, nPics, mPicArray;
function myResizeAll()
{
nFiles = pictures.files.length;
nSized = 0;
nPics = 0;
mPicArray = [];
// work out how many of the chosen files are images
for (var i=0; i<nFiles; i++)
{
if (pictures.files[i].type.indexOf("image") != -1)
nPics++;
}
// now try to load the ones that are images
for (var i=0; i<nFiles; i++)
{
if (pictures.files[i].type.indexOf("image") != -1)
loadFileObject( pictures.files[i], onFileDataLoaded );
}
}
// callback gets data via the .target.result field of the param passed to it.
function loadFileObject(fileObj, loadedCallback)
{
var reader = new FileReader();
reader.onload = loadedCallback;
reader.readAsDataURL( fileObj );
}
function onFileDataLoaded(e)
{
var tmpImg = newEl('img');
tmpImg.addEventListener('load', onImgElemLoaded, false);
tmpImg.src = e.target.result;
}
function onImgElemLoaded(evt)
{
// create a canvas
var can = newEl('canvas');
var ctx = can.getContext('2d');
// scale it
var scale = 0.5;
can.width = this.width * scale;
can.height = this.height * scale;
// draw scaled image
ctx.drawImage(this, 0, 0, can.width, can.height);
// get dataURL
var resizedImgDataURL = can.toDataURL();
mPicArray.push( resizedImgDataURL );
nSized++;
// when all image files have been loaded, then loaded as image elements and finally resized on a canvas,
// submit the data.
if (nSized == nPics)
{
document.getElementById("sizedpics").value= JSON.stringify(mPicArray);
document.forms["frm"].submit();
}
}
</script>
</head>
<body>
<input type="file" id="pictures" multiple><br>
<form id="frm" action="save.php" method="POST">
<input type="hidden" name='sizedpics' id="sizedpics"/>
<button type="button" onclick="myResizeAll()">submit!</button>
</form>
<canvas id="canvas" style='display:none' width="800"></canvas><br>
</body>
</html>
save.php
<?php
$imgArray = json_decode( $_POST['sizedpics'] );
print_r( count($imgArray) );
$numPics = count($imgArray);
for ($i=0; $i<$numPics; $i++)
{
printf("<img src='%s'/>\n", $imgArray[$i]);
}
?>
Output
Your English is just fine.It's better than that of many native-speakers. ;)
来源:https://stackoverflow.com/questions/28773631/append-canvas-images-to-input-array-with-javascript