上传之前调整图像大小 - 将画布转换为File对象 [英] Resize image before upload - convert canvas to a File object

查看:237
本文介绍了上传之前调整图像大小 - 将画布转换为File对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我现在使用HTML5 File API上传多个图片的代码片段:

  / ** 
* @param {FileList}文件
* /
上传:函数(文件){
nfiles = files.length;

(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);


$ b $ / code $ / pre
$ b $我想调整使用canvas对象上传图片之前,但没有经验,我不知道如何更新代码使用技术,例如这里描述的一个: HTML5上传前预先调整图像大小



canvas.toDataURL(image / png); 将返回一个编码的字符串。但是我需要发布 File 对象。

编辑



您如何为大多数现代浏览器编写(合理)跨浏览器功能来调整文件的大小上传,处理JPG,PNG和GIF透明度:

  / ** 
* @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){}


解决方案



$ pre $函数调整大小,
canvas = document.createElement('canvas'),
context = null,
imageObj = new Image(),
blob = null;

//创建一个隐藏的画布对象,我们可以使用它来创建新的调整大小的图像数据
canvas.id =hiddenCanvas;
canvas.width = max_width;
canvas.height = max_height;
canvas.style.visibility =hidden;
document.body.appendChild(canvas);

//获取上下文以使用
context = canvas.getContext('2d');

//检查图像,然后
//触发文件加载器从图像中获取数据
if(file.type.match('image。*') ){
fileLoader.readAsDataURL(file);
} else {
alert('文件不是图片');


//设置文件加载器的加载函数
//一旦文件加载器将数据传递给
//映像对象,图像已经加载,
//触发图像onload函数
fileLoader.onload = function(){
var data = this.result;
imageObj.src = data;
};

fileLoader.onabort = function(){
alert(上传被中止了。
};

fileLoader.onerror = function(){
alert(读取文件时发生错误。
};


//设置清除隐藏画布上下文的图像onload函数,
//绘制新图像,然后从中获取blob数据
imageObj。 onload = function(){

//检查空图像
if(this.width == 0 || this.height == 0){
alert('Image是空的');
} 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函数在这里可用:
// http://stackoverflow.com/questions/12168909/blob-from-dataurl
// add' )'在这个函数的末尾SO不允许更新它没有6字符编辑
blob = dataURItoBlob(canvas.toDataURL(imageEncoding));

//将这个blob传递给你的上传函数
upload(blob);
}
};

imageObj.onabort = function(){
alert(Image load was aborted。);
};

imageObj.onerror = function(){
alert(加载图片时发生错误。
};




请注意:

使用文件加载器并加载图像意味着有一些延迟,因此函数是异步的,所以试图简单地返回blob数据将无法工作。你需要等待加载发生,然后才能使用加载的数据,并启动每个文件的上传功能。

另外文件加载器可能有一些浏览器兼容性问题,但我不认为这是可能的任何其他方式客户端。


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);

    }
}

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"); will return an encoded string. But I need to post the File object.

Edit

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){}

解决方案

Try something like this:

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.");
    };

}

Please note:

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.

这篇关于上传之前调整图像大小 - 将画布转换为File对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆