问题描述
这是我现在使用 HTML5 File API 上传多张图片的代码片段:
Here's the code fragment I'm using now to upload multiple images using HTML5 File API:
/**
* @param {FileList} files
*/
upload: function(files){
nfiles = files.length;
for (var i = 0; i < nfiles; i++) {
/** @var file File **/
var file = files[i];
var xhr = new XMLHttpRequest();
xhr.open("POST", settings.post_upload, true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.upload.filenumb = i;
xhr.filenumb = i;
xhr.upload.filename = file.name;
var nef = new FormData();
nef.append("folder", settings.folder);
nef.append("file_element", settings.file_elem);
nef.append("udata", settings.user_data);
nef.append(settings.file_elem, file);
xhr.send(nef);
}
}
我想调整图像的大小之前使用画布对象上传,但没有这方面的经验,我不确定如何使用技术更新代码,例如此处描述的内容:HTML5 上传前调整图片大小
I'd like to resize the images before upload using canvas object, but not having experience with this, I'm not sure how can update the code using techniques, e.g. the one described here: HTML5 Pre-resize images before uploading
canvas.toDataURL("image/png");
将返回一个编码字符串.但我需要发布 File
对象.
canvas.toDataURL("image/png");
will return an encoded string. But I need to post the File
object.
您将如何(合理地)为大多数现代浏览器编写跨浏览器功能,以便在上传之前调整文件大小、处理透明的 jpg、png 和 gif:
How would you write (reasonably) cross browser function for most modern browsers to resize the File before upload, handling jpg,png and gifs with transparency:
/**
* @param {File} file
* @param int max_width
* @param int max_height
* @param float compression_ratio
* @returns File
*/
function resize(file, max_width, max_height, compression_ratio){}
推荐答案
试试这样的:
function resize(file, max_width, max_height, compression_ratio, imageEncoding){
var fileLoader = new FileReader(),
canvas = document.createElement('canvas'),
context = null,
imageObj = new Image(),
blob = null;
//create a hidden canvas object we can use to create the new resized image data
canvas.id = "hiddenCanvas";
canvas.width = max_width;
canvas.height = max_height;
canvas.style.visibility = "hidden";
document.body.appendChild(canvas);
//get the context to use
context = canvas.getContext('2d');
// check for an image then
//trigger the file loader to get the data from the image
if (file.type.match('image.*')) {
fileLoader.readAsDataURL(file);
} else {
alert('File is not an image');
}
// setup the file loader onload function
// once the file loader has the data it passes it to the
// image object which, once the image has loaded,
// triggers the images onload function
fileLoader.onload = function() {
var data = this.result;
imageObj.src = data;
};
fileLoader.onabort = function() {
alert("The upload was aborted.");
};
fileLoader.onerror = function() {
alert("An error occured while reading the file.");
};
// set up the images onload function which clears the hidden canvas context,
// draws the new image then gets the blob data from it
imageObj.onload = function() {
// Check for empty images
if(this.width == 0 || this.height == 0){
alert('Image is empty');
} else {
context.clearRect(0,0,max_width,max_height);
context.drawImage(imageObj, 0, 0, this.width, this.height, 0, 0, max_width, max_height);
//dataURItoBlob function available here:
// http://stackoverflow.com/questions/12168909/blob-from-dataurl
// add ')' at the end of this function SO dont allow to update it without a 6 character edit
blob = dataURItoBlob(canvas.toDataURL(imageEncoding));
//pass this blob to your upload function
upload(blob);
}
};
imageObj.onabort = function() {
alert("Image load was aborted.");
};
imageObj.onerror = function() {
alert("An error occured while loading image.");
};
}
请注意:
使用文件加载器和加载图像意味着存在一些延迟,因此该函数是异步的,因此试图简单地返回 blob 数据是行不通的.您需要等待加载发生,然后才能使用加载的数据并为每个文件触发对上传函数的调用.
Working with fileloaders and loading images means there are some delays and the function is therefore asynchronous so trying to simply return the blob data wont work. You need to wait for the loading to occur before you can use the loaded data and fire off a call to your upload function for EACH file.
文件加载器也可能存在一些浏览器兼容性问题,但我认为这在客户端的任何其他方式都是不可能的.
Also fileloader may have some browser compatability issues but I don't think this is possible any other way client side.
这篇关于上传前调整图像大小 - 将画布转换为文件对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!