使用Javascript / AngularJS上传已调整大小的图像

时间:2016-01-25 15:05:52

标签: javascript angularjs image resize image-resizing

我们正在构建一个用户可以上传图像的应用程序,但我需要在将图像上传到服务器之前调整图像大小。该文件的输入是输入[type = file],我们检查图像是否有效。如果有效,我们继续以下请求:

Upload.upload({url: url, data: {file: input.x}, headers: {'Authorization': token}});

输入变量是HTML中输入字段的值。当我们不需要调整图像大小时,此代码非常有用。不幸的是,这只是一个完美世界的情况。经过一段时间寻找相同的问题,我似乎找到了使用以下函数的解决方案:

var resize = function(size, url, callback) {
    var temp = new Image();
    temp.onload = function() {
        var target = { width: temp.width, height: temp.height, aspect: temp.width / temp.height };

        if (temp.width > temp.height) {
            size = Math.min(temp.width, size);
            target.width = size; target.height = size / target.aspect;
        } else {
            size = Math.min(temp.height, size);
            target.height = size; target.width = size * target.aspect;
        }

        var canvas = document.createElement('canvas');
        canvas.width = target.width; canvas.height = target.height;

        var ctx = canvas.getContext('2d');
        ctx.drawImage(this, 0, 0, temp.width, temp.height, 0, 0, target.width, target.height);

        callback(canvas.toDataURL(url.split(',')[0].split(':')[1].split(';')[0]));
    }; temp.src = url;
}

这看起来效果很好。我需要传递一个Base64字符串。所以我将upload方法包装在以下内容中:

var reader = new FileReader();  
reader.onload = function(e) {
    resize(1000, e.target.result, function(done) {
        console.log(done);
        Upload.upload({url: url, data: {file: done}, headers: {'Authorization': UserService.getToken()}});
    });
}
reader.readAsDataURL(file);

这样我传递一个包含图像的Base64字符串,甚至看起来像是一个魅力。但最大的问题是,服务器需要一个真正的文件而不是Base64字符串。所以上传本身就失败了。

我在Convert Data URI to File then append to FormData找到了应该解决此问题的功能,但事实并非如此。我从链接添加方法后将方法更改为此方法:

var reader = new FileReader();  
reader.onload = function(e) {
    resize(1000, e.target.result, function(done) {
        console.log(done);
        Upload.upload({url: url, data: {file: dataURItoBlob(done)}, headers: {'Authorization': UserService.getToken()}});
    });
}
reader.readAsDataURL(file);

你们有没有人知道如何将Base64字符串再次更改回文件?我发现很多帖子解释了我如何在浏览器中显示它们,但没有解决我的问题将其作为文件上传。

1 个答案:

答案 0 :(得分:0)

对不起这个问题。但似乎dataURItoBlob函数工作正常,但blob中没有原始文件名,所以我无法立即上传它。我更改了resize函数,因此它会立即执行这两个操作,结果就是:

var resize = function(size, url, name, callback) {
    var temp = new Image();
    temp.onload = function() {
        var target = { width: temp.width, height: temp.height, aspect: temp.width / temp.height };

        if (temp.width > temp.height) {
            size = Math.min(temp.width, size);
            target.width = size; target.height = size / target.aspect;
        } else {
            size = Math.min(temp.height, size);
            target.height = size; target.width = size * target.aspect;
        }

        var canvas = document.createElement('canvas');
        canvas.width = target.width; canvas.height = target.height;

        var ctx = canvas.getContext('2d');
        ctx.drawImage(this, 0, 0, temp.width, temp.height, 0, 0, target.width, target.height);

        var type = url.split(',')[0].split(':')[1].split(';')[0];
        var data = canvas.toDataURL(type);

        //callback(data);

        var bytes = (data.split(',')[0].indexOf('base64') >= 0) ? atob(data.split(',')[1]) : unescape(dataURI.split(',')[1]);

        var ia = new Uint8Array(bytes.length);
        for(var i = 0; i < bytes.length; i++) { ia[i] = bytes.charCodeAt(i); }

        var blb = new Blob([ia], {type : type});
        blb.name = name;

        callback(blb);
    }; temp.src = url;
};

要上传文件,请执行以下操作:

var deferred = $q.defer();
var reader = new FileReader();
reader.onload = function(e) {
    resize(maxSize, e.target.result, image.name, function(done) {
        deferred.resolve(Upload.upload({url: url, data: {file: done}, headers: {'Authorization': token}));
    });
}
reader.readAsDataURL(image);

return deferred.promise;