misc: undo file orientation when resizing images (#73872)
gitea/wcs/pipeline/head This commit looks good Details

This commit is contained in:
Benjamin Dauvergne 2023-03-07 12:55:25 +01:00
parent 15051e2c2d
commit 28bac2af67
3 changed files with 1165 additions and 40 deletions

View File

@ -87,6 +87,7 @@ class HTTPResponse(quixote.http_response.HTTPResponse):
'jquery.js', 'jquery.js',
'jquery-ui.js', 'jquery-ui.js',
'jquery.iframe-transport.js', 'jquery.iframe-transport.js',
'exif.js',
'jquery.fileupload.js', 'jquery.fileupload.js',
] ]
) )

1064
wcs/qommon/static/js/exif.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -255,49 +255,109 @@ $.WcsFileUpload = {
var original_image_64 = e.target.result; var original_image_64 = e.target.result;
var img = document.createElement("img"); var img = document.createElement("img");
img.onload = function() { img.onload = function() {
var canvas = document.createElement("canvas"); var adapt_image = function(orientation) {
var ctx = canvas.getContext('2d'); /*
ctx.drawImage(img, 0, 0); * 1 = Horizontal (normal)
* 2 = Mirror horizontal
var MAX_WIDTH = 2000; * 3 = Rotate 180
var MAX_HEIGHT = 2000; * 4 = Mirror vertical
var width = img.width; * 5 = Mirror horizontal and rotate 270 CW
var height = img.height; * 6 = Rotate 90 CW
* 7 = Mirror horizontal and rotate 90 CW
if (width > height && width > MAX_WIDTH) { * 8 = Rotate 270 CW */
height *= MAX_WIDTH / width; var canvas = document.createElement("canvas");
width = MAX_WIDTH;
} else if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
if (img.width != width || img.height != height) {
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d'); var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, width, height); ctx.drawImage(img, 0, 0);
var new_image_64 = canvas.toDataURL('image/jpeg', 0.95);
var blob = null; var MAX_WIDTH = 2000;
if (data.files[0].type == 'image/jpeg') { var MAX_HEIGHT = 2000;
blob = ExifRestorer.restore_as_blob(original_image_64, new_image_64); var width = img.width;
blob.name = data.files[0].name; var height = img.height;
} else {
// adapted from dataURItoBlob, from if (width > height && width > MAX_WIDTH) {
// https://stackoverflow.com/questions/12168909/blob-from-dataurl#12300351 height *= MAX_WIDTH / width;
var byteString = atob(new_image_64.split(',')[1]); width = MAX_WIDTH;
var mimeString = new_image_64.split(',')[0].split(':')[1].split(';')[0] } else if (height > MAX_HEIGHT) {
var ab = new ArrayBuffer(byteString.length); width *= MAX_HEIGHT / height;
var ia = new Uint8Array(ab); height = MAX_HEIGHT;
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
blob = new Blob([ab], {type: mimeString});
blob.name = data.files[0].name + '.jpg';
} }
data.files[0] = blob; if (img.width != width || img.height != height) {
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
switch (orientation) {
case 1:
break;
case 2:
ctx.translate(width, 0);
ctx.scale(-1, 1);
break;
case 3:
ctx.translate(width, height);
ctx.rotate(180 / 180 * Math.PI);
break;
case 4:
ctx.translate(0, height);
ctx.scale(1, -1);
break;
case 5:
canvas.width = height;
canvas.height = width;
ctx.rotate(90 / 180 * Math.PI);
ctx.scale(1, -1);
break;
case 6:
canvas.width = height;
canvas.height = width;
ctx.rotate(-90 / 180 * Math.PI);
ctx.translate(-width, 0);
break;
case 7:
canvas.width = height;
canvas.height = width;
ctx.rotate(270 / 180 * Math.PI);
ctx.translate(-width, height);
ctx.scale(1, -1);
break;
case 8:
canvas.width = height;
canvas.height = width;
ctx.translate(height, 0);
ctx.rotate(-270 / 180 * Math.PI);
break;
}
ctx.drawImage(img, 0, 0, width, height);
var new_image_64 = canvas.toDataURL('image/jpeg', 0.95);
var blob = null;
if (data.files[0].type == 'image/jpeg') {
blob = ExifRestorer.restore_as_blob(original_image_64, new_image_64);
blob.name = data.files[0].name;
} else {
// adapted from dataURItoBlob, from
// https://stackoverflow.com/questions/12168909/blob-from-dataurl#12300351
var byteString = atob(new_image_64.split(',')[1]);
var mimeString = new_image_64.split(',')[0].split(':')[1].split(';')[0]
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
blob = new Blob([ab], {type: mimeString});
blob.name = data.files[0].name + '.jpg';
}
data.files[0] = blob;
}
$(base_widget).find('.file-button').trigger('wcs:image-blob', data.files[0]);
return $.WcsFileUpload.upload(base_widget, data);
};
if (data.files[0].type == 'image/jpeg') {
EXIF.getData(img, function () {
var orientation = +EXIF.getTag(this, "Orientation");
adapt_image(orientation);
});
} else {
adapt_image(0);
} }
$(base_widget).find('.file-button').trigger('wcs:image-blob', data.files[0]);
return $.WcsFileUpload.upload(base_widget, data);
} }
img.src = e.target.result; img.src = e.target.result;
} }