我是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;
}
};
}
]);
答案 0 :(得分:2)
你的问题非常简单。
只要您不附加任何事件,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>");
}
&#13;
console{
font-family: Consolas, monaco, monospace;
}
&#13;
<script type="text/javascript" src="https://code.jquery.com/jquery-latest.min.js"></script>
<console></console>
&#13;
您的代码示例
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';
}
&#13;
<canvas id="canvas"></canvas>
&#13;
答案 1 :(得分:0)
<script type="text/javascript">
window.onload = function(){
//Whatever you want to do when it has finished loading here
}
</script>
您可以将这段代码放在HTML中或JavaScript文件中的某个位置,然后不使用脚本标记;)
希望这适合你:D
答案 2 :(得分:0)
我遇到了问题,图片画布总是空白。
然后我拖延了,现在工作正常。
setTimeout(function () {
var da = document.getElementById("canvasFabric").toDataURL("png", "1");
$('#FInalImage').attr("src", canvasFabric.toDataURL("png", "1"));
window.open(da);
}, 100);