mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-23 23:11:27 +00:00
Merge pull request #5333 from jonasgeiler/staging
Improve media filtering by using OffscreenCanvas, if supported
This commit is contained in:
commit
aea5392044
1 changed files with 68 additions and 33 deletions
|
@ -1095,11 +1095,12 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
defineErrorMessage(errObject) {
|
defineErrorMessage(errObject) {
|
||||||
|
let msg;
|
||||||
if (errObject.response) {
|
if (errObject.response) {
|
||||||
let msg = errObject.response.data.message ? errObject.response.data.message : 'An unexpected error occured.';
|
msg = errObject.response.data.message ? errObject.response.data.message : 'An unexpected error occured.';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let msg = errObject.message;
|
msg = errObject.message;
|
||||||
}
|
}
|
||||||
return swal('Oops, something went wrong!', msg, 'error');
|
return swal('Oops, something went wrong!', msg, 'error');
|
||||||
},
|
},
|
||||||
|
@ -1765,57 +1766,91 @@ export default {
|
||||||
|
|
||||||
applyFilterToMedia() {
|
applyFilterToMedia() {
|
||||||
// this is where the magic happens
|
// this is where the magic happens
|
||||||
var ua = navigator.userAgent.toLowerCase();
|
|
||||||
if(ua.indexOf('firefox') == -1 && ua.indexOf('chrome') == -1) {
|
|
||||||
this.isPosting = false;
|
|
||||||
swal('Oops!', 'Your browser does not support the filter feature.', 'error');
|
|
||||||
this.page = 3;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let count = this.media.filter(m => m.filter_class).length;
|
let count = this.media.filter(m => m.filter_class).length;
|
||||||
if(count) {
|
if(count) {
|
||||||
this.page = 'filteringMedia';
|
this.page = 'filteringMedia';
|
||||||
this.filteringRemainingCount = count;
|
this.filteringRemainingCount = count;
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.isFilteringMedia = true;
|
this.isFilteringMedia = true;
|
||||||
this.media.forEach((media, idx) => this.applyFilterToMediaSave(media, idx));
|
Promise.all(this.media.map(media => {
|
||||||
|
return this.applyFilterToMediaSave(media);
|
||||||
|
})).catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
swal('Oops!', 'An error occurred while applying filters to your media. Please refresh the page and try again. If the problem persist, please try a different web browser.', 'error');
|
||||||
|
});
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.page = 3;
|
this.page = 3;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
applyFilterToMediaSave(media, idx) {
|
async applyFilterToMediaSave(media) {
|
||||||
if(!media.filter_class) {
|
if(!media.filter_class) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let self = this;
|
// Load image
|
||||||
let data = null;
|
const image = document.createElement('img');
|
||||||
const canvas = document.createElement('canvas');
|
|
||||||
const ctx = canvas.getContext('2d');
|
|
||||||
let image = document.createElement('img');
|
|
||||||
image.src = media.url;
|
image.src = media.url;
|
||||||
image.addEventListener('load', e => {
|
await new Promise((resolve, reject) => {
|
||||||
|
image.addEventListener('load', () => resolve());
|
||||||
|
image.addEventListener('error', () => {
|
||||||
|
reject(new Error('Failed to load image'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create canvas
|
||||||
|
let canvas;
|
||||||
|
let usingOffscreenCanvas = false;
|
||||||
|
if('OffscreenCanvas' in window) {
|
||||||
|
canvas = new OffscreenCanvas(image.width, image.height);
|
||||||
|
usingOffscreenCanvas = true;
|
||||||
|
} else {
|
||||||
|
canvas = document.createElement('canvas');
|
||||||
canvas.width = image.width;
|
canvas.width = image.width;
|
||||||
canvas.height = image.height;
|
canvas.height = image.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw image with filter to canvas
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
if (!ctx) {
|
||||||
|
throw new Error('Failed to get canvas context');
|
||||||
|
}
|
||||||
|
if (!('filter' in ctx)) {
|
||||||
|
throw new Error('Canvas filter not supported');
|
||||||
|
}
|
||||||
ctx.filter = App.util.filterCss[media.filter_class];
|
ctx.filter = App.util.filterCss[media.filter_class];
|
||||||
ctx.drawImage(image, 0, 0, image.width, image.height);
|
ctx.drawImage(image, 0, 0, image.width, image.height);
|
||||||
ctx.save();
|
ctx.save();
|
||||||
canvas.toBlob(function(blob) {
|
|
||||||
data = new FormData();
|
// Convert canvas to blob
|
||||||
|
let blob;
|
||||||
|
if(usingOffscreenCanvas) {
|
||||||
|
blob = await canvas.convertToBlob({
|
||||||
|
type: media.mime,
|
||||||
|
quality: 1,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
blob = await new Promise((resolve, reject) => {
|
||||||
|
canvas.toBlob(blob => {
|
||||||
|
if(blob) {
|
||||||
|
resolve(blob);
|
||||||
|
} else {
|
||||||
|
reject(
|
||||||
|
new Error('Failed to convert canvas to blob'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, media.mime, 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload blob / Update media
|
||||||
|
const data = new FormData();
|
||||||
data.append('file', blob);
|
data.append('file', blob);
|
||||||
data.append('id', media.id);
|
data.append('id', media.id);
|
||||||
axios.post('/api/compose/v0/media/update', data)
|
await axios.post('/api/compose/v0/media/update', data);
|
||||||
.then(res => {
|
media.is_filtered = true;
|
||||||
self.media[idx].is_filtered = true;
|
this.updateFilteringMedia();
|
||||||
self.updateFilteringMedia();
|
|
||||||
}).catch(err => {
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}, media.mime, 0.9);
|
|
||||||
ctx.clearRect(0, 0, image.width, image.height);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
updateFilteringMedia() {
|
updateFilteringMedia() {
|
||||||
|
|
Loading…
Reference in a new issue