Resize images before upload in web UI to reduce bandwidth (#7223)

* Resize images before upload in web UI to reduce bandwidth

Fix #7218

* Fix issues

* Do not resize GIFs in JS
This commit is contained in:
Eugen Rochko 2018-04-23 00:43:36 +02:00 committed by GitHub
parent 75c4ab9d12
commit 05fb6f096d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 85 additions and 10 deletions

View File

@ -174,6 +174,79 @@ export function submitComposeFail(error) {
}; };
}; };
const MAX_IMAGE_DIMENSION = 1280;
const dataURLtoBlob = dataURL => {
const BASE64_MARKER = ';base64,';
if (dataURL.indexOf(BASE64_MARKER) === -1) {
const parts = dataURL.split(',');
const contentType = parts[0].split(':')[1];
const raw = parts[1];
return new Blob([raw], { type: contentType });
}
const parts = dataURL.split(BASE64_MARKER);
const contentType = parts[0].split(':')[1];
const raw = window.atob(parts[1]);
const rawLength = raw.length;
const uInt8Array = new Uint8Array(rawLength);
for (let i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: contentType });
};
const resizeImage = (inputFile, callback) => {
if (inputFile.type.match(/image.*/) && inputFile.type !== 'image/gif') {
const reader = new FileReader();
reader.onload = e => {
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
const { width, height } = img;
let newWidth, newHeight;
if (width < MAX_IMAGE_DIMENSION && height < MAX_IMAGE_DIMENSION) {
callback(inputFile);
return;
}
if (width > height) {
newHeight = height * MAX_IMAGE_DIMENSION / width;
newWidth = MAX_IMAGE_DIMENSION;
} else if (height > width) {
newWidth = width * MAX_IMAGE_DIMENSION / height;
newHeight = MAX_IMAGE_DIMENSION;
} else {
newWidth = MAX_IMAGE_DIMENSION;
newHeight = MAX_IMAGE_DIMENSION;
}
canvas.width = newWidth;
canvas.height = newHeight;
canvas.getContext('2d').drawImage(img, 0, 0, newWidth, newHeight);
callback(dataURLtoBlob(canvas.toDataURL(inputFile.type)));
};
img.src = e.target.result;
};
reader.readAsDataURL(inputFile);
} else {
callback(inputFile);
}
};
export function uploadCompose(files) { export function uploadCompose(files) {
return function (dispatch, getState) { return function (dispatch, getState) {
if (getState().getIn(['compose', 'media_attachments']).size > 3) { if (getState().getIn(['compose', 'media_attachments']).size > 3) {
@ -182,17 +255,19 @@ export function uploadCompose(files) {
dispatch(uploadComposeRequest()); dispatch(uploadComposeRequest());
let data = new FormData(); resizeImage(files[0], file => {
data.append('file', files[0]); let data = new FormData();
data.append('file', file);
api(getState).post('/api/v1/media', data, { api(getState).post('/api/v1/media', data, {
onUploadProgress: function (e) { onUploadProgress: function (e) {
dispatch(uploadComposeProgress(e.loaded, e.total)); dispatch(uploadComposeProgress(e.loaded, e.total));
}, },
}).then(function (response) { }).then(function (response) {
dispatch(uploadComposeSuccess(response.data)); dispatch(uploadComposeSuccess(response.data));
}).catch(function (error) { }).catch(function (error) {
dispatch(uploadComposeFail(error)); dispatch(uploadComposeFail(error));
});
}); });
}; };
}; };