Convert image uploads into webp files unless it's a gif (closes #11)
This commit is contained in:
parent
4a2c40397f
commit
73601c579c
4 changed files with 54 additions and 8 deletions
|
|
@ -5,11 +5,9 @@ import { ArtistBrowser } from "./apps/ArtistBrowser.mjs";
|
|||
import { ImageApp } from "./apps/ImageApp.mjs";
|
||||
|
||||
// Utils
|
||||
import { getFileSize, hashFile, lastModifiedAt } from "./utils/fs.mjs";
|
||||
import { convertToWebp, getFileSize, hashFile, lastModifiedAt } from "./utils/fs.mjs";
|
||||
|
||||
const { deepFreeze } = foundry.utils;
|
||||
|
||||
export const api = deepFreeze({
|
||||
export const api = foundry.utils.deepFreeze({
|
||||
Apps: {
|
||||
ArtBrowser,
|
||||
ArtistBrowser,
|
||||
|
|
@ -18,6 +16,7 @@ export const api = deepFreeze({
|
|||
},
|
||||
utils: {
|
||||
fs: {
|
||||
convertToWebp,
|
||||
hashFile,
|
||||
lastModifiedAt,
|
||||
getFileSize,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { __ID__, filePath } from "../consts.mjs";
|
||||
import { determineFileExtension, getFile, hashFile, lastModifiedAt, uploadFile, uploadJson } from "../utils/fs.mjs";
|
||||
import { convertToWebp, determineFileExtension, getFile, hashFile, lastModifiedAt, uploadFile, uploadJson } from "../utils/fs.mjs";
|
||||
import { DBConnectorMixin } from "./mixins/DBConnector.mjs";
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
|
@ -147,7 +147,7 @@ export class ImageApp extends
|
|||
this.#artistCache.push({ value: id, label: artist.name });
|
||||
};
|
||||
};
|
||||
console.log(this._doc);
|
||||
|
||||
const ctx = {
|
||||
meta: {
|
||||
idp: this.id,
|
||||
|
|
@ -170,7 +170,7 @@ export class ImageApp extends
|
|||
#file = null;
|
||||
async #changeImage(event) {
|
||||
/** @type {File} */
|
||||
const file = this.#file = event.target.files[0];
|
||||
let file = this.#file = event.target.files[0];
|
||||
|
||||
// Prevent memory leaks
|
||||
URL.revokeObjectURL(this._doc.path);
|
||||
|
|
@ -185,7 +185,15 @@ export class ImageApp extends
|
|||
};
|
||||
|
||||
// Ensure we don't already have the file uploaded
|
||||
const extension = determineFileExtension(file);
|
||||
const webp = await convertToWebp(file);
|
||||
let extension;
|
||||
if (webp) {
|
||||
file = this.#file = webp;
|
||||
extension = `webp`;
|
||||
} else {
|
||||
extension = determineFileExtension(file);
|
||||
};
|
||||
|
||||
const hash = await hashFile(file);
|
||||
const path = `storage/tokens/${hash}.${extension}`;
|
||||
const lastModified = await lastModifiedAt(path);
|
||||
|
|
|
|||
3
module/config.mjs
Normal file
3
module/config.mjs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export const config = CONFIG.ImageTagger = foundry.utils.deepSeal({
|
||||
WEBP_IGNORE: [`image/gif`],
|
||||
});
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
import { config } from "../config.mjs";
|
||||
import { __ID__, devMode, filePath } from "../consts.mjs";
|
||||
|
||||
const { fetchJsonWithTimeout } = foundry.utils;
|
||||
|
|
@ -28,6 +29,41 @@ export async function hashFile(file) {
|
|||
.join(``);
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts an image file into a webp file unless it is already a webp file or
|
||||
* cannot be converted to a webp, in which case it doesn't modify the file at all.
|
||||
*
|
||||
* @param {File} file The file to convert
|
||||
* @returns {Promise<File>}
|
||||
*/
|
||||
export async function convertToWebp(file) {
|
||||
if (file.type === `image/webp`) { return null };
|
||||
if (config.WEBP_IGNORE.includes(file.type)) { return null };
|
||||
|
||||
/** @type {HTMLImageElement} */
|
||||
const image = document.createElement(`img`);
|
||||
const url = URL.createObjectURL(file);
|
||||
image.src = url;
|
||||
await image.decode();
|
||||
|
||||
/** @type {HTMLCanvasElement} */
|
||||
const canvas = document.createElement(`canvas`);
|
||||
canvas.width = image.naturalWidth;
|
||||
canvas.height = image.naturalHeight;
|
||||
canvas.getContext(`2d`).drawImage(image, 0, 0);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
canvas.toBlob(
|
||||
(blob) => {
|
||||
const name = file.name.split(`.`).slice(0, -1).join(`.`);
|
||||
const webp = new File([blob], `${name}.webp`, { type: blob.type });
|
||||
resolve(webp);
|
||||
},
|
||||
`image/webp`,
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
export async function lastModifiedAt(path) {
|
||||
try {
|
||||
const response = await fetch(filePath(path), { method: `HEAD` });
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue