如何创建包含 canvas 元素的承诺
How to create a promise which contains a canvas element
我在将缩略图生成函数转换为 Promise 时遇到了一些问题。
我需要它,以便它在生成缩略图后运行 Promise.all,目前缩略图未定义(这是有道理的,因为它需要先生成)。
我不明白第一个 img.onload 部分,我的解决方法是将它设置在 $scope 上,我知道这是一种糟糕的数据传递方式。
var img = new Image;
img.onload = resizeImage;
img.src = $scope.imageData;
function resizeImage() {
var newDataUri = imageToDataUri(this, 100, 100);
$scope.imageDataThumb = newDataUri;
$scope.$apply();
}
function imageToDataUri(img, width, height) {
// create an off-screen canvas
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
var quality = 1.0;
return canvas.toDataURL('image/jpeg', quality).split(",")[1]; // quality = [0.0, 1.0]
}
var imgGuid = factory.guid();
//Save the image to storage
console.log($scope.imageDataThumb);
Promise.all([fireBaseService.postImageToStorage(imageData, "images", imgGuid), fireBaseService.postImageToStorage($scope.imageDataThumb, "images", "thumb_" + imgGuid)])
.then(function (results) {
//do stuff with results
});
I need to have it so it runs the Promise.all once the thumbnail has been generated,
None canvas 中的图像导出功能将 return 承诺:
toDataURL()
DOMString = canvas.toDataURL(type, encoderOptions); // synchronous
toBlob()
void canvas.toBlob(callback, mimeType, qualityArgument); // asynchronous
唯一的方法是手动将你的函数包装到一个 Promise 中(尽管,对于 toDataURL()
这样的同步函数,这没有什么意义。如果你只生成一个缩略图,我建议将图像加载到由于图像加载是异步的,因此承诺更有意义。):
function imageToDataUri(img, width, height) {
return new Promise(function(success, reject) {
// create an off-screen canvas
var ctx = document.createElement('canvas').getContext("2d");
ctx.canvas.width = width;
ctx.canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
var quality = 1.0;
setTimeout(function() {
success(canvas.toDataURL('image/jpeg', quality).split(",")[1]); //quality=[0.0,1.0]
}, 4); // make call async
})
}
现在您可以将调用用作任何承诺:
var promise = imageToDataUri(img, width, height);
promise.then(function(str) { ... });
或
Promise.all([promise, promise2, ...])
.then( ... );
另外一个小提示:通过将 header 与 data-uri 分开,它不再是 Data-URL,只是一个 Base-64 编码的字符串 - 函数名称需要考虑的事情.
我在将缩略图生成函数转换为 Promise 时遇到了一些问题。
我需要它,以便它在生成缩略图后运行 Promise.all,目前缩略图未定义(这是有道理的,因为它需要先生成)。
我不明白第一个 img.onload 部分,我的解决方法是将它设置在 $scope 上,我知道这是一种糟糕的数据传递方式。
var img = new Image;
img.onload = resizeImage;
img.src = $scope.imageData;
function resizeImage() {
var newDataUri = imageToDataUri(this, 100, 100);
$scope.imageDataThumb = newDataUri;
$scope.$apply();
}
function imageToDataUri(img, width, height) {
// create an off-screen canvas
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
var quality = 1.0;
return canvas.toDataURL('image/jpeg', quality).split(",")[1]; // quality = [0.0, 1.0]
}
var imgGuid = factory.guid();
//Save the image to storage
console.log($scope.imageDataThumb);
Promise.all([fireBaseService.postImageToStorage(imageData, "images", imgGuid), fireBaseService.postImageToStorage($scope.imageDataThumb, "images", "thumb_" + imgGuid)])
.then(function (results) {
//do stuff with results
});
I need to have it so it runs the Promise.all once the thumbnail has been generated,
None canvas 中的图像导出功能将 return 承诺:
toDataURL()
DOMString = canvas.toDataURL(type, encoderOptions); // synchronous
toBlob()
void canvas.toBlob(callback, mimeType, qualityArgument); // asynchronous
唯一的方法是手动将你的函数包装到一个 Promise 中(尽管,对于 toDataURL()
这样的同步函数,这没有什么意义。如果你只生成一个缩略图,我建议将图像加载到由于图像加载是异步的,因此承诺更有意义。):
function imageToDataUri(img, width, height) {
return new Promise(function(success, reject) {
// create an off-screen canvas
var ctx = document.createElement('canvas').getContext("2d");
ctx.canvas.width = width;
ctx.canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
var quality = 1.0;
setTimeout(function() {
success(canvas.toDataURL('image/jpeg', quality).split(",")[1]); //quality=[0.0,1.0]
}, 4); // make call async
})
}
现在您可以将调用用作任何承诺:
var promise = imageToDataUri(img, width, height);
promise.then(function(str) { ... });
或
Promise.all([promise, promise2, ...])
.then( ... );
另外一个小提示:通过将 header 与 data-uri 分开,它不再是 Data-URL,只是一个 Base-64 编码的字符串 - 函数名称需要考虑的事情.