使用 JavaScript 将 canvas 图像附加到输入数组
Append canvas images to input array with JavaScript
我正在尝试让我的代码工作,但我没有成功。
基本上我想要的是将调整大小算法应用于用户选择的多个图像,使它们成为 HTML5 Canvas 然后将每个字符串(DataURL)插入输入数组中以通过 POST方法。
我的代码(客户端)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>
我的代码(服务器)save.php
<?php
print_r(count($_POST['sizedpics']));exit();
?>
我认为与 javascript 同步有问题,但我不知道如何解决,我需要使用单个输入 "sizedpics".
大家知道错误在哪里吗?
感谢阅读,请原谅我糟糕的英文写作方式:-)
编辑: 更新了答案中的评论和更新的代码。
有很多事情阻止了你的代码工作,唉,我累了,在我去的时候忘了记下它们,忘记了细节。 :(
您不妨查看以下代码。
它使用 fileReader 和方法 .readAsDataURL
加载图像。然后在完成时触发用户提供的回调。然后此回调方法尝试将 dataURL 作为图像加载。当(如果!)成功时,图像被绘制到缩放的 canvas 上,然后检索 canvas 的 dataURL。此 dataURL 被添加到一个数组中,并将缩放图像的数量与 selected 图像的数量进行比较。当两个数字匹配时,它 JSON 对数组进行编码并将其填充到隐藏输入中,然后再提交表单。
在php端,我们获取提交的数据并JSON对其进行解码。然后我们在输出每个元素作为图像的 src 之前显示此数组中图像数量的计数,以确认上传成功。
我添加了代码以确保所选文件在进一步处理之前是图像。您可以 select 文件的混合列表,并且只处理图像。 我不处理所选文件是图像但尝试将其加载到 img 元素失败的情况。
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]);
}
?>
输出
你的英语比许多母语人士的英语好fine.It。 ;)
我正在尝试让我的代码工作,但我没有成功。 基本上我想要的是将调整大小算法应用于用户选择的多个图像,使它们成为 HTML5 Canvas 然后将每个字符串(DataURL)插入输入数组中以通过 POST方法。
我的代码(客户端)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>
我的代码(服务器)save.php
<?php
print_r(count($_POST['sizedpics']));exit();
?>
我认为与 javascript 同步有问题,但我不知道如何解决,我需要使用单个输入 "sizedpics".
大家知道错误在哪里吗? 感谢阅读,请原谅我糟糕的英文写作方式:-)
编辑: 更新了答案中的评论和更新的代码。
有很多事情阻止了你的代码工作,唉,我累了,在我去的时候忘了记下它们,忘记了细节。 :(
您不妨查看以下代码。
它使用 fileReader 和方法 .readAsDataURL
加载图像。然后在完成时触发用户提供的回调。然后此回调方法尝试将 dataURL 作为图像加载。当(如果!)成功时,图像被绘制到缩放的 canvas 上,然后检索 canvas 的 dataURL。此 dataURL 被添加到一个数组中,并将缩放图像的数量与 selected 图像的数量进行比较。当两个数字匹配时,它 JSON 对数组进行编码并将其填充到隐藏输入中,然后再提交表单。
在php端,我们获取提交的数据并JSON对其进行解码。然后我们在输出每个元素作为图像的 src 之前显示此数组中图像数量的计数,以确认上传成功。
我添加了代码以确保所选文件在进一步处理之前是图像。您可以 select 文件的混合列表,并且只处理图像。 我不处理所选文件是图像但尝试将其加载到 img 元素失败的情况。
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]);
}
?>
输出
你的英语比许多母语人士的英语好fine.It。 ;)