我是javascript的初学者。我正在尝试在客户端上调整图像大小,然后再将其上传到我的服务器进行存储,我找到了一种使用HTML5 Canvas进行操作的方法:http : //hacks.mozilla.org/2011/01/how-to-develop- a-html5-image-uploader /
我的问题:它一直在上传空白图片。我认为空白图像的原因是,当我从画布上抓取图像时,画布未完成绘制。当我从画布上抓取图像之前设置3秒的windows.timeout时,一切正常。有没有比超时更可靠的方法?还是有其他方法可以调整客户端图像的大小?
我进行客户端图像大小调整的原因是因为我正在与上载不必要的大文件的人打交道,并且我认为进行客户端图像大小调整最有效。
感谢您的任何提示/答案!
//resize image
Resizeimage.resize(file);
//***if i wrap this part with timeout it works
var canvas = document.getElementById('canvas');
var data = canvas.toDataURL(file.type);
// convert base64/URLEncoded data component to raw binary data held in a string
var bytestring;
if (data.split(',')[0].indexOf('base64') >= 0)
bytestring = atob(data.split(',')[1]);
else
bytestring = escape(data.split(',')[1]);
//get imagetype
var mimeString = data.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(bytestring.length);
for (var i = 0; i < bytestring.length; i++) {
ia[i] = bytestring.charCodeAt(i);
}
// create a blob from array
var blob = new Blob([ia], {
type: mimeString
});
//upload files
$scope.upload = $upload.upload({
url: 'articles/imageUpload',
method: 'POST',
file: blob
//update progress bar
}).progress(function(event) {
$scope.uploadInProgress = true;
$scope.uploadProgress = Math.floor(event.loaded / event.total * 100);
//file upload success
}).success(function(data, status, headers, config) {
$scope.uploadInProgress = false;
$scope.uploadedImage = JSON.parse(data);
$scope.isDisabled = false;
//file upload fail
}).error(function(err) {
$scope.uploadInProgress = false;
console.log('Error uploading file: ' + err.message || err);
});
//***
angular.module('articles').factory('Resizeimage', [
function() {
var imgSelectorStr = null;
// Resizeimage service logic
function render(src) {
var image = new Image();
image.onload = function() {
var canvas = document.getElementById('canvas');
//check the greater out of width and height
if (image.height > image.width) {
image.width *= 945 / image.height;
image.height = 945;
} else {
image.height *= 945 / image.width;
image.width = 945;
}
//draw (&resize) image to canvas
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0, image.width, image.height);
};
image.src = src;
}
function loadImage(src) {
// Create fileReader and run the result through the render
var reader = new FileReader();
reader.onload = function(e) {
render(e.target.result);
};
reader.readAsDataURL(src);
}
// Public API
return {
resize: function(src) {
loadImage(src);
return true;
}
};
}
]);
您的问题很简单。
只要您不附加任何事件,JavaScript就会一个接一个地运行一条语句(您需要这样做,因为您希望在抓取图像时执行所有语句)。
例如,如果将代码附加到事件上image.onload
,那么这部分代码将等待该事件,而其余代码将继续异步进行。
因此,您是对的-尝试抓住图像时不会绘制图像。
通过超时(效率最低/最不安全)来解决问题的不良方式是,通过将图像抓取代码包装在一个函数中,并在调整图像大小后运行此函数来更好地解决此问题。就像您用于同步异步事件的回调一样。
例子
/* setTimeout will behave like an event */
setTimeout(
function(){
$('console').append("<div>SetTimeout</div>");
SynchCodeAfterTimeout();
}, 1000);
AsynchCodeAfterTimeout();
function AsynchCodeAfterTimeout(){
$('console').append("<div>AsynchCodeAfterTimeout</div>");
}
function SynchCodeAfterTimeout(){
$('console').append("<div>SynchCodeAfterTimeout</div>");
}
console{
font-family: Consolas, monaco, monospace;
}
<script type="text/javascript" src="https://code.jquery.com/jquery-latest.min.js"></script>
<console></console>
代码示例
render();
// Resizeimage service logic
function render() {
var image = new Image();
image.onload = function() {
var canvas = document.getElementById('canvas');
//check the greater out of width and height
if (image.height > image.width) {
image.width *= 945 / image.height;
image.height = 945;
} else {
image.height *= 945 / image.width;
image.width = 945;
}
//draw (&resize) image to canvas
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0, image.width, image.height);
/*timeout not needed its just there so the browser renders the canvas contents so you can see them when the alert pops up*/
setTimeout(function() {
alert('yey all the drawing is done (this is synchronous)');
});
};
image.src = 'https://loremflickr.com/320/240';
}
<canvas id="canvas"></canvas>
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句