Resize image before upload - convert canvas to a File object(上传前调整图像大小 - 将画布转换为文件对象)
问题描述
这是我现在使用 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.
这篇关于上传前调整图像大小 - 将画布转换为文件对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:上传前调整图像大小 - 将画布转换为文件对象
基础教程推荐
- 如何使用TypeScrip将固定承诺数组中的项设置为可选 2022-01-01
- 自定义 XMLHttpRequest.prototype.open 2022-01-01
- Chart.js 在线性图表上拖动点 2022-01-01
- Vue 3 – <过渡>渲染不能动画的非元素根节点 2022-01-01
- 我可以在浏览器中与Babel一起使用ES模块,而不捆绑我的代码吗? 2022-01-01
- 直接将值设置为滑块 2022-01-01
- Electron 将 Node.js 和 Chromium 上下文结合起来意味着 2022-01-01
- 用于 Twitter 小部件宽度的 HTML/CSS 2022-01-01
- 如何使用JIT在顺风css中使用布局变体? 2022-01-01
- html表格如何通过更改悬停边框来突出显示列? 2022-01-01