return 如何与 img.onload 一起工作?
How to return function with img.onload?
我目前正在构建一个应用程序,用户可以在其中上传多张图像并同时使用它们。由于某些进程由于大图像文件而执行不佳,我想在用户获取它们之前调整它们的大小。
在我的 resizer()
函数中,我尝试使用 canvas 调整大小。它有效,但由于 'canvas.toDataURL()' 在 img.onload
函数内部,我不知道如何 return 值并将其解析为 handleFiles()
函数。
另外...我尝试了一些情况,其中我从 handleFiles()
获得了一些代码 - 例如:
var preview = document.getElementById("img"+count);
var surface = document.getElementById("cubface"+count);
var count = counterImg();
preview.src = resizer(e.target.result, count);
surface.src = resizer(e.target.result, count);
并将它们放在 img.onload
函数的末尾,如
var preview = document.getElementById("img"+number);
var surface = document.getElementById("cubface"+number);
preview.src = canvas.toDataURL;
surface.src = canvas.toDataURL;
我得到了调整大小,但我只得到了循环中要处理的最后一张图像。
所以问题是:
在resizer()
函数中,如何returnimg.onload
中的canvas.toDataURL
值?
为什么循环只覆盖最后一个实例而不是所有图像,如何解决?
完整代码:
JavaScript:
function resizer(base64, number){
// Max size for thumbnail
if(typeof(maxWidth) === 'undefined') maxWidth = 1200;
if(typeof(maxHeight) === 'undefined') maxHeight = 1200;
var img = new Image();
img.src = base64;
// Create and initialize two canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var canvasCopy = document.createElement("canvas");
var copyContext = canvasCopy.getContext("2d");
img.onload = function() {
// Determine new ratio based on max size
var ratio = 1;
if (img.width > maxWidth)
ratio = maxWidth / img.width;
else if (img.height > maxHeight)
ratio = maxHeight / img.height;
// Draw original image in second canvas
canvasCopy.width = img.width;
canvasCopy.height = img.height;
copyContext.drawImage(img, 0, 0);
// Copy and resize second canvas to first canvas
canvas.width = img.width * ratio;
canvas.height = img.height * ratio;
ctx.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvas.width, canvas.height);
return canvas.toDataURL();
};
return img.onload;
}
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
var count = counterImg();
var preview = document.getElementById("img"+count);
var surface = document.getElementById("cubface"+count);
var reader = new FileReader();
reader.onload = (function (preview, surface) {
return function (e) {
var newimage = resizer(e.target.result, count);
preview.src = newimage;
surface.src = newimage;
$('#image-cropper'+count).cropit('imageSrc', e.target.result);
}
})(preview, surface);
reader.readAsDataURL(file);
}
}
变量计数的范围不正确。
函数的声明时间和使用时间之间存在延迟,因此,每次执行都以相同的值结束。所以 jquery 选择器总是 return 相同的元素。这就解释了为什么只有最后一张图片被修改了。
这是一个演示执行的 jsfiddle。
https://jsfiddle.net/Lc6bngv5/1/
要解决此问题,只需将计数传递给封装预览和表面的函数即可:
reader.onload = (function (preview, surface, count) {
return function (e) {
var newimage = resizer(e.target.result, count);
preview.src = newimage;
surface.src = newimage;
$('#image-cropper'+count).cropit('imageSrc', e.target.result);
}
})(preview, surface, count);
第二个问题:
调整大小函数return是一个函数。它不是 return 该函数的结果。要正确获取 url,我会使用回调函数:
reader.onload = (function (preview, surface, count) {
return function (e) {
var newimage = resizer(e.target.result, count, function(url){
preview.src = url;
surface.src = url;
$('#image-cropper'+count).cropit('imageSrc', e.target.result);
});
}
})(preview, surface, count);
并且您必须在调整大小时进行以下更改:
function resizer(base64, number, cb){
...
img.onload = function() {
...
// return canvas.toDataURL();
cb(canvas.toDataURL());
};
}
我目前正在构建一个应用程序,用户可以在其中上传多张图像并同时使用它们。由于某些进程由于大图像文件而执行不佳,我想在用户获取它们之前调整它们的大小。
在我的 resizer()
函数中,我尝试使用 canvas 调整大小。它有效,但由于 'canvas.toDataURL()' 在 img.onload
函数内部,我不知道如何 return 值并将其解析为 handleFiles()
函数。
另外...我尝试了一些情况,其中我从 handleFiles()
获得了一些代码 - 例如:
var preview = document.getElementById("img"+count);
var surface = document.getElementById("cubface"+count);
var count = counterImg();
preview.src = resizer(e.target.result, count);
surface.src = resizer(e.target.result, count);
并将它们放在 img.onload
函数的末尾,如
var preview = document.getElementById("img"+number);
var surface = document.getElementById("cubface"+number);
preview.src = canvas.toDataURL;
surface.src = canvas.toDataURL;
我得到了调整大小,但我只得到了循环中要处理的最后一张图像。
所以问题是:
在
resizer()
函数中,如何returnimg.onload
中的canvas.toDataURL
值?为什么循环只覆盖最后一个实例而不是所有图像,如何解决?
完整代码:
JavaScript:
function resizer(base64, number){
// Max size for thumbnail
if(typeof(maxWidth) === 'undefined') maxWidth = 1200;
if(typeof(maxHeight) === 'undefined') maxHeight = 1200;
var img = new Image();
img.src = base64;
// Create and initialize two canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var canvasCopy = document.createElement("canvas");
var copyContext = canvasCopy.getContext("2d");
img.onload = function() {
// Determine new ratio based on max size
var ratio = 1;
if (img.width > maxWidth)
ratio = maxWidth / img.width;
else if (img.height > maxHeight)
ratio = maxHeight / img.height;
// Draw original image in second canvas
canvasCopy.width = img.width;
canvasCopy.height = img.height;
copyContext.drawImage(img, 0, 0);
// Copy and resize second canvas to first canvas
canvas.width = img.width * ratio;
canvas.height = img.height * ratio;
ctx.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvas.width, canvas.height);
return canvas.toDataURL();
};
return img.onload;
}
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
var count = counterImg();
var preview = document.getElementById("img"+count);
var surface = document.getElementById("cubface"+count);
var reader = new FileReader();
reader.onload = (function (preview, surface) {
return function (e) {
var newimage = resizer(e.target.result, count);
preview.src = newimage;
surface.src = newimage;
$('#image-cropper'+count).cropit('imageSrc', e.target.result);
}
})(preview, surface);
reader.readAsDataURL(file);
}
}
变量计数的范围不正确。
函数的声明时间和使用时间之间存在延迟,因此,每次执行都以相同的值结束。所以 jquery 选择器总是 return 相同的元素。这就解释了为什么只有最后一张图片被修改了。
这是一个演示执行的 jsfiddle。
https://jsfiddle.net/Lc6bngv5/1/
要解决此问题,只需将计数传递给封装预览和表面的函数即可:
reader.onload = (function (preview, surface, count) {
return function (e) {
var newimage = resizer(e.target.result, count);
preview.src = newimage;
surface.src = newimage;
$('#image-cropper'+count).cropit('imageSrc', e.target.result);
}
})(preview, surface, count);
第二个问题:
调整大小函数return是一个函数。它不是 return 该函数的结果。要正确获取 url,我会使用回调函数:
reader.onload = (function (preview, surface, count) {
return function (e) {
var newimage = resizer(e.target.result, count, function(url){
preview.src = url;
surface.src = url;
$('#image-cropper'+count).cropit('imageSrc', e.target.result);
});
}
})(preview, surface, count);
并且您必须在调整大小时进行以下更改:
function resizer(base64, number, cb){
...
img.onload = function() {
...
// return canvas.toDataURL();
cb(canvas.toDataURL());
};
}