在上传前使用HTML5调整图片大小 [英] Use HTML5 to resize an image before upload

查看:247
本文介绍了在上传前使用HTML5调整图片大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了几个不同的帖子,甚至问题stackoverflow回答这个问题。我基本上实现了与此帖相同的功能。



所以这里是我的问题。当我上传照片时,我还需要提交其余的表格。这是我的html:

 < form id =uploadImageFormenctype =multipart / form-data> 
< input name =imagefile []type =fileid =takePictureFieldaccept =image / *onchange =uploadPhotos(\'#{imageUploadUrl} \')/> ;
< input id =namevalue =#{name}/>
...几个输入...
< / form>

以前,我不需要调整图像大小,所以我的javascript看起来像这样:

  window.uploadPhotos = function(url){
var data = new FormData($(form [id * ='uploadImageForm '])[0]);

$ .ajax({
url:url,
data:data,
cache:false,
contentType:false,
processData :false,
type:'POST',
success:function(data){
... handle error ...
}
}
});
};

这一切都很好...现在我需要调整图像大小...替换窗体中的图像,以便发布调整大小的图像,而不是上传的图像?

  window.uploadPhotos = function ){

var resizedImage;

//读入文件
var file = event.target.files [0];

//确保它是一个图像
if(file.type.match(/ image。* /)){
console.log('已加载图像') ;

//加载图片
var reader = new FileReader();
reader.onload = function(readerEvent){
var image = new Image();
image.onload = function(imageEvent){

//调整图片大小
var canvas = document.createElement('canvas'),
max_size = 1200,
width = image.width,
height = image.height;
if(width> height){
if(width> max_size){
height * = max_size / width;
width = max_size;
}
} else {
if(height> max_size){
width * = max_size / height;
height = max_size;
}
}
canvas.width = width;
canvas.height = height;
canvas.getContext('2d')。drawImage(image,0,0,width,height);
resizedImage = canvas.toDataURL('image / jpeg');
}
image.src = readerEvent.target.result;
}
reader.readAsDataURL(file);
}


// TODO:需要一些逻辑来切换哪张照片被发布...

var data = new FormData $(form [id * ='uploadImageForm'])[0]);

$ .ajax({
url:url,
data:data,
cache:false,
contentType:false,
processData :false,
type:'POST',
success:function(data){
... handle error ...
}
}
});
};

我曾想过将文件输入移出表单并在表单中有一个隐藏的输入我设置的值为调整大小的图像的值...但我想知道我是否可以替换已经在窗体中的图像。



首先,我将文件输入移到表单之外,这样它就可以未提交:

 < input name =imagefile []type =fileid =takePictureFieldaccept = image / *onchange =uploadPhotos(\'#{imageUploadUrl} \')/> 
< form id =uploadImageFormenctype =multipart / form-data>
< input id =namevalue =#{name}/>
...几个输入...
< / form>

然后我更改了 uploadPhotos 只调整大小:

  window.uploadPhotos = function(url){
//读入文件
var file = event.target.files [0];

//确保它是一个图像
if(file.type.match(/ image。* /)){
console.log('已加载图像') ;

//加载图片
var reader = new FileReader();
reader.onload = function(readerEvent){
var image = new Image();
image.onload = function(imageEvent){

//调整图片大小
var canvas = document.createElement('canvas'),
max_size = 544, // TODO:pull max size from a site config
width = image.width,
height = image.height;
if(width> height){
if(width> max_size){
height * = max_size / width;
width = max_size;
}
} else {
if(height> max_size){
width * = max_size / height;
height = max_size;
}
}
canvas.width = width;
canvas.height = height;
canvas.getContext('2d')。drawImage(image,0,0,width,height);
var dataUrl = canvas.toDataURL('image / jpeg');
var resizedImage = dataURLToBlob(dataUrl);
$ .event.trigger({
type:imageResized,
blob:resizedImage,
url:dataUrl
});
}
image.src = readerEvent.target.result;
}
reader.readAsDataURL(file);
}
};

正如你所看到的,我使用 canvas.toDataURL('image / jpeg'); 将调整大小的图像更改为一个dataUrl adn然后我调用函数 dataURLToBlob(dataUrl); 将dataUrl转换为blob然后我可以附加到表单。当blob创建时,我触发一个自定义事件。下面是创建blob的函数:

  / *将画布转换为BLOB的效用函数* / 
var dataURLToBlob = function(dataURL){
var BASE64_MARKER ='; base64,';
if(dataURL.indexOf(BASE64_MARKER)== -1){
var parts = dataURL.split(',');
var contentType = parts [0] .split(':')[1];
var raw = parts [1];

return new Blob([raw],{type:contentType});
}

var parts = dataURL.split(BASE64_MARKER);
var contentType = parts [0] .split(':')[1];
var raw = window.atob(parts [1]);
var rawLength = raw.length;

var uInt8Array = new Uint8Array(rawLength);

for(var i = 0; i uInt8Array [i] = raw.charCodeAt(i);
}

return new Blob([uInt8Array],{type:contentType});
}
/ * End将画布转换为BLOB的效用函数* /

最后,这里是我的事件处理程序,从自定义事件中获取blob,追加表单,然后提交。

  / *处理图片调整大小的事件* / 
$(document).on(imageResized,function(event){
var data = new FormData($(form [id * ='uploadImageForm'] )[0]);
if(event.blob&& event.url){
data.append('image_data',event.blob);

$ .ajax({
url:event.url,
data:data,
cache:false,
contentType:false,
processData:false,
type:'POST',
success:function(data){
... handle errors ...
}
});
}
});


I have found a few different posts and even questions on stackoverflow answering this question. I am basically implementing this same thing as this post.

So here is my issue. When I upload the photo, I also need to submit the rest of the form. Here is my html:

<form id="uploadImageForm" enctype="multipart/form-data">
  <input name="imagefile[]" type="file" id="takePictureField" accept="image/*" onchange="uploadPhotos(\'#{imageUploadUrl}\')" />
  <input id="name" value="#{name}" />
  ... a few more inputs ... 
</form>

Previously, I did not need to resize the image, so my javascript looked like this:

window.uploadPhotos = function(url){
    var data = new FormData($("form[id*='uploadImageForm']")[0]);

    $.ajax({
        url: url,
        data: data,
        cache: false,
        contentType: false,
        processData: false,
        type: 'POST',
        success: function(data){
            ... handle error...
            }
        }
    });
};

This all worked great... now that I need to resize the images... how can I replace the image in the form so that the resized one is posted and not the uploaded image?

window.uploadPhotos = function(url){

    var resizedImage;

    // Read in file
    var file = event.target.files[0];

    // Ensure it's an image
    if(file.type.match(/image.*/)) {
        console.log('An image has been loaded');

        // Load the image
        var reader = new FileReader();
        reader.onload = function (readerEvent) {
            var image = new Image();
            image.onload = function (imageEvent) {

                // Resize the image
                var canvas = document.createElement('canvas'),
                    max_size = 1200,
                    width = image.width,
                    height = image.height;
                if (width > height) {
                    if (width > max_size) {
                        height *= max_size / width;
                        width = max_size;
                    }
                } else {
                    if (height > max_size) {
                        width *= max_size / height;
                        height = max_size;
                    }
                }
                canvas.width = width;
                canvas.height = height;
                canvas.getContext('2d').drawImage(image, 0, 0, width, height);
                resizedImage = canvas.toDataURL('image/jpeg');
            }
            image.src = readerEvent.target.result;
        }
        reader.readAsDataURL(file);
    }


   // TODO: Need some logic here to switch out which photo is being posted...

    var data = new FormData($("form[id*='uploadImageForm']")[0]);

    $.ajax({
        url: url,
        data: data,
        cache: false,
        contentType: false,
        processData: false,
        type: 'POST',
        success: function(data){
            ... handle error...
            }
        }
    });
};

I've thought about moving the file input out of the form and having a hidden input in the form that I set the value of to the value of the resized image... But I'm wondering if I can just replace the image that is already in the form.

解决方案

Here is what I ended up doing and it worked great.

First I moved the file input outside of the form so that it is not submitted:

<input name="imagefile[]" type="file" id="takePictureField" accept="image/*" onchange="uploadPhotos(\'#{imageUploadUrl}\')" />
<form id="uploadImageForm" enctype="multipart/form-data">
    <input id="name" value="#{name}" />
    ... a few more inputs ... 
</form>

Then I changed the uploadPhotos function to handle only the resizing:

window.uploadPhotos = function(url){
    // Read in file
    var file = event.target.files[0];

    // Ensure it's an image
    if(file.type.match(/image.*/)) {
        console.log('An image has been loaded');

        // Load the image
        var reader = new FileReader();
        reader.onload = function (readerEvent) {
            var image = new Image();
            image.onload = function (imageEvent) {

                // Resize the image
                var canvas = document.createElement('canvas'),
                    max_size = 544,// TODO : pull max size from a site config
                    width = image.width,
                    height = image.height;
                if (width > height) {
                    if (width > max_size) {
                        height *= max_size / width;
                        width = max_size;
                    }
                } else {
                    if (height > max_size) {
                        width *= max_size / height;
                        height = max_size;
                    }
                }
                canvas.width = width;
                canvas.height = height;
                canvas.getContext('2d').drawImage(image, 0, 0, width, height);
                var dataUrl = canvas.toDataURL('image/jpeg');
                var resizedImage = dataURLToBlob(dataUrl);
                $.event.trigger({
                    type: "imageResized",
                    blob: resizedImage,
                    url: dataUrl
                });
            }
            image.src = readerEvent.target.result;
        }
        reader.readAsDataURL(file);
    }
};

As you can see I'm using canvas.toDataURL('image/jpeg'); to change the resized image into a dataUrl adn then I call the function dataURLToBlob(dataUrl); to turn the dataUrl into a blob that I can then append to the form. When the blob is created, I trigger a custom event. Here is the function to create the blob:

/* Utility function to convert a canvas to a BLOB */
var dataURLToBlob = function(dataURL) {
    var BASE64_MARKER = ';base64,';
    if (dataURL.indexOf(BASE64_MARKER) == -1) {
        var parts = dataURL.split(',');
        var contentType = parts[0].split(':')[1];
        var raw = parts[1];

        return new Blob([raw], {type: contentType});
    }

    var parts = dataURL.split(BASE64_MARKER);
    var contentType = parts[0].split(':')[1];
    var raw = window.atob(parts[1]);
    var rawLength = raw.length;

    var uInt8Array = new Uint8Array(rawLength);

    for (var i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
    }

    return new Blob([uInt8Array], {type: contentType});
}
/* End Utility function to convert a canvas to a BLOB      */

Finally, here is my event handler that takes the blob from the custom event, appends the form and then submits it.

/* Handle image resized events */
$(document).on("imageResized", function (event) {
    var data = new FormData($("form[id*='uploadImageForm']")[0]);
    if (event.blob && event.url) {
        data.append('image_data', event.blob);

        $.ajax({
            url: event.url,
            data: data,
            cache: false,
            contentType: false,
            processData: false,
            type: 'POST',
            success: function(data){
               ... handle errors...
            }
        });
    }
});

这篇关于在上传前使用HTML5调整图片大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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