通过 javascript 循环上传多张 canvas 图片
Upload multiple canvas images through javascript loop
我正在尝试制作一个上传脚本,在 saveimage.php 处理之前调整客户端的多张图片。这是因为它们将被上传到互联网可能非常慢的外部位置。
我已经能够在这里找到帮助我将其组合在一起的代码片段。我只是一个初学者,所以它可能很乱!
它目前所做的是检查何时在 'file_input' 字段中输入文件。然后它查看文件的数量并循环遍历它们,直到每个文件都已放入 canvas 并在其中上传。
但是,问题是: 当我没有为每个文件添加警报时,循环速度太快,例如只处理 10 张图像中的 1 或 2 张.因为上传脚本会比 canvas 可以用新图片更新更快。
这是我的当前页面,已简化为核心:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
</head>
<body>
<form>
<input id="file_input" type='file' multiple />
</form>
<div id="preview">
<canvas id="canvas"></canvas>
</div>
<script>
var input = document.getElementById('file_input');
input.addEventListener('change', handleFiles);
function handleFiles(e) {
var files = input.files;
alert(files.length +" files are being uploaded!"); // display amount of files for testing purpose
for (var i = 0; i < files.length; ++i) {
alert("Upload file number: "+i); // display file # for testing purpose, when this is removed the script will go too fast
var MAX_HEIGHT = 1000;
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image;
img.onload = function(){
if(img.height > MAX_HEIGHT) {
img.width *= MAX_HEIGHT / img.height;
img.height = MAX_HEIGHT;
}
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
preview.style.width = img.width + "px";
preview.style.height = img.height + "px";
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
// the canvas should contain an image now and this will send it through saveimage.php
var myDrawing = document.getElementById("canvas");
var drawingString = myDrawing.toDataURL("image/jpeg", 0.5);
var postData = "canvasData="+drawingString;
var ajax = new XMLHttpRequest();
ajax.open("POST",'saveimage.php',true);
ajax.setRequestHeader('Content-Type', 'canvas/upload');
ajax.onreadystatechange=function()
{
if (ajax.readyState == 4);
}
ajax.send(postData);
};
img.src = URL.createObjectURL(e.target.files[i]);
}
}
</script>
</body>
</html>
这是我的 saveimage.php 效果很好,但只是为了完整的概述:
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
$rawImage=$GLOBALS['HTTP_RAW_POST_DATA'];
$removeHeaders=substr($rawImage, strpos($rawImage, ",")+1);
$decode=base64_decode($removeHeaders);
// check if the file already exists and keep adding +1 intil it's unique
$i = 1;
while(file_exists('uploads/image'.$i.'.jpg')) {
$i++;
}
$fopen = fopen( 'uploads/image'.$i.'.jpg', 'wb' );
fwrite( $fopen, $decode);
fclose( $fopen );
}
?>
一点额外信息:
- 我添加了canvas,因为据我所知这是
调整图像客户端大小的唯一方法。在最终脚本中它将是
设置为隐藏。
- 如果canvas可以跳过,数据发送到saveimage.php
我想这也能立即解决问题。
- 正如我所说,我对 javascript 不是很有经验,所以如果有
更简单的方法来实现这个目标。请告诉我!
提前致谢!
在onload回调中使用this
关键字(而不是img
)为当前图像,img
may/will在for循环之前被覆盖回调触发。
img.height --> this.height
等
还有你使用自定义内容类型而不是 application/x-www-form-urlencoded
的原因吗?
Url 编码的表单数据更容易处理。
JavaScript 异步加载图像。这意味着一旦为它分配了新图像的 .src,它将开始加载图像,但同时会在 .src 之后继续处理 javascript,而图像需要时间来加载。
您在 for 循环中使用了相同的图像变量 (var img
)。因此,每次通过循环,您都会在上一个图像完全加载之前覆盖上一个 img。
这是一个图像加载器,它可以完全加载所有图像,然后调用 start() 函数,您可以在其中进行处理:
// image loader
// put the paths to your images in imageURLs[]
var imageURLs=[];
imageURLs.push("myImage1.png");
imageURLs.push("myImage2.png");
// etc, etc.
// the loaded images will be placed in imgs[]
var imgs=[];
var imagesOK=0;
loadAllImages(start);
function loadAllImages(callback){
for (var i=0; i<imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function(){
imagesOK++;
if (imagesOK>=imageURLs.length ) {
callback();
}
};
img.onerror=function(){alert("image load failed");}
img.crossOrigin="anonymous";
img.src = imageURLs[i];
}
}
function start(){
// the imgs[] array now holds fully loaded images
// the imgs[] are in the same order as imageURLs[]
}
我已经为同样的问题苦苦挣扎了一段时间,但我终于
使用其他人的代码拼凑出另一个解决方案,他们已经解决了这个问题,
它有效。它可能并不完美,我欢迎任何改进建议。
这个概念是你有两个 Javascript
Resize0 和 Resize1 相同的函数,它们互相调用
直到所有照片都调整大小然后调整大小的功能
最后一张图片提交表格。两个Function之间传递参数
彼此这样他们中的一个就会知道什么时候提交表格。
其中两个参数是 Number_Of_Images 和当前 Image_Number。
您还可以从
http://www.wantitconsulting.co.nz/ExampleResizeUpload.zip。
您需要在测试网站的基本目录中创建一个文件夹
图像进入。文件夹名称是 TestResizeUpload。服务器
边使用 php.
我正在尝试制作一个上传脚本,在 saveimage.php 处理之前调整客户端的多张图片。这是因为它们将被上传到互联网可能非常慢的外部位置。
我已经能够在这里找到帮助我将其组合在一起的代码片段。我只是一个初学者,所以它可能很乱!
它目前所做的是检查何时在 'file_input' 字段中输入文件。然后它查看文件的数量并循环遍历它们,直到每个文件都已放入 canvas 并在其中上传。
但是,问题是: 当我没有为每个文件添加警报时,循环速度太快,例如只处理 10 张图像中的 1 或 2 张.因为上传脚本会比 canvas 可以用新图片更新更快。
这是我的当前页面,已简化为核心:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
</head>
<body>
<form>
<input id="file_input" type='file' multiple />
</form>
<div id="preview">
<canvas id="canvas"></canvas>
</div>
<script>
var input = document.getElementById('file_input');
input.addEventListener('change', handleFiles);
function handleFiles(e) {
var files = input.files;
alert(files.length +" files are being uploaded!"); // display amount of files for testing purpose
for (var i = 0; i < files.length; ++i) {
alert("Upload file number: "+i); // display file # for testing purpose, when this is removed the script will go too fast
var MAX_HEIGHT = 1000;
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image;
img.onload = function(){
if(img.height > MAX_HEIGHT) {
img.width *= MAX_HEIGHT / img.height;
img.height = MAX_HEIGHT;
}
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
preview.style.width = img.width + "px";
preview.style.height = img.height + "px";
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
// the canvas should contain an image now and this will send it through saveimage.php
var myDrawing = document.getElementById("canvas");
var drawingString = myDrawing.toDataURL("image/jpeg", 0.5);
var postData = "canvasData="+drawingString;
var ajax = new XMLHttpRequest();
ajax.open("POST",'saveimage.php',true);
ajax.setRequestHeader('Content-Type', 'canvas/upload');
ajax.onreadystatechange=function()
{
if (ajax.readyState == 4);
}
ajax.send(postData);
};
img.src = URL.createObjectURL(e.target.files[i]);
}
}
</script>
</body>
</html>
这是我的 saveimage.php 效果很好,但只是为了完整的概述:
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
$rawImage=$GLOBALS['HTTP_RAW_POST_DATA'];
$removeHeaders=substr($rawImage, strpos($rawImage, ",")+1);
$decode=base64_decode($removeHeaders);
// check if the file already exists and keep adding +1 intil it's unique
$i = 1;
while(file_exists('uploads/image'.$i.'.jpg')) {
$i++;
}
$fopen = fopen( 'uploads/image'.$i.'.jpg', 'wb' );
fwrite( $fopen, $decode);
fclose( $fopen );
}
?>
一点额外信息:
- 我添加了canvas,因为据我所知这是 调整图像客户端大小的唯一方法。在最终脚本中它将是 设置为隐藏。
- 如果canvas可以跳过,数据发送到saveimage.php 我想这也能立即解决问题。
- 正如我所说,我对 javascript 不是很有经验,所以如果有 更简单的方法来实现这个目标。请告诉我!
提前致谢!
在onload回调中使用this
关键字(而不是img
)为当前图像,img
may/will在for循环之前被覆盖回调触发。
img.height --> this.height
等
还有你使用自定义内容类型而不是 application/x-www-form-urlencoded
的原因吗?
Url 编码的表单数据更容易处理。
JavaScript 异步加载图像。这意味着一旦为它分配了新图像的 .src,它将开始加载图像,但同时会在 .src 之后继续处理 javascript,而图像需要时间来加载。
您在 for 循环中使用了相同的图像变量 (var img
)。因此,每次通过循环,您都会在上一个图像完全加载之前覆盖上一个 img。
这是一个图像加载器,它可以完全加载所有图像,然后调用 start() 函数,您可以在其中进行处理:
// image loader
// put the paths to your images in imageURLs[]
var imageURLs=[];
imageURLs.push("myImage1.png");
imageURLs.push("myImage2.png");
// etc, etc.
// the loaded images will be placed in imgs[]
var imgs=[];
var imagesOK=0;
loadAllImages(start);
function loadAllImages(callback){
for (var i=0; i<imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function(){
imagesOK++;
if (imagesOK>=imageURLs.length ) {
callback();
}
};
img.onerror=function(){alert("image load failed");}
img.crossOrigin="anonymous";
img.src = imageURLs[i];
}
}
function start(){
// the imgs[] array now holds fully loaded images
// the imgs[] are in the same order as imageURLs[]
}
我已经为同样的问题苦苦挣扎了一段时间,但我终于 使用其他人的代码拼凑出另一个解决方案,他们已经解决了这个问题, 它有效。它可能并不完美,我欢迎任何改进建议。 这个概念是你有两个 Javascript Resize0 和 Resize1 相同的函数,它们互相调用 直到所有照片都调整大小然后调整大小的功能 最后一张图片提交表格。两个Function之间传递参数 彼此这样他们中的一个就会知道什么时候提交表格。 其中两个参数是 Number_Of_Images 和当前 Image_Number。 您还可以从 http://www.wantitconsulting.co.nz/ExampleResizeUpload.zip。 您需要在测试网站的基本目录中创建一个文件夹 图像进入。文件夹名称是 TestResizeUpload。服务器 边使用 php.