angularjsクライアントで画像ファイルを圧縮してアップロード
主にhtml 5のcanvasを利用して画像の圧縮を行い、dataURLに変換し、dataURLをBlobファイルに変換することで、Blobオブジェクトを直接Formdataに付与することができる.
現在angualrjsではmultiform dataによるファイルのアップロードはしばらくサポートされていないため、formdataのファイルをアップロードするには以下のコードを利用します.
app.service('Util', function($q) {
var dataURItoBlob = function(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {
type: mimeString
});
};
var resizeFile = function(file) {
var deferred = $q.defer();
var img = document.createElement("img");
try {
var reader = new FileReader();
reader.onload = function(e) {
img.src = e.target.result;
//resize the image using canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var MAX_WIDTH = 800;
var MAX_HEIGHT = 800;
var width = img.width;
var height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
//change the dataUrl to blob data for uploading to server
var dataURL = canvas.toDataURL('image/jpeg');
var blob = dataURItoBlob(dataURL);
deferred.resolve(blob);
};
reader.readAsDataURL(file);
} catch (e) {
deferred.resolve(e);
}
return deferred.promise;
};
return {
resizeFile: resizeFile
};
});
現在angualrjsではmultiform dataによるファイルのアップロードはしばらくサポートされていないため、formdataのファイルをアップロードするには以下のコードを利用します.
app.controller('CompanyCtrl', function($http, Util) {
Util.resizeFile(input.files[0]).then(function(blob_data) {
var fd = new FormData();
fd.append("imageFile", blob_data);
$http.post('http://your.domain.com/upload', fd, {
headers: {'Content-Type': undefined },
transformRequest: angular.identity
})
.success(function(data) {
$scope.model.company_pict = data[0];
})
.error(function() {
console.log("uploaded error...")
});
}, function(err_reason) {
console.log(err_reason);
});
}