Add very basic support of APNG

This commit is contained in:
SillyLossy
2023-05-17 14:47:34 +03:00
parent 76bfd42adc
commit c48af795da

View File

@@ -869,18 +869,11 @@ app.post("/deletecharacter", urlencodedParser, function (request, response) {
async function charaWrite(img_url, data, target_img, response = undefined, mes = 'ok', crop = undefined) { async function charaWrite(img_url, data, target_img, response = undefined, mes = 'ok', crop = undefined) {
try { try {
// Read the image, resize, and save it as a PNG into the buffer // Read the image, resize, and save it as a PNG into the buffer
let rawImg = await jimp.read(img_url); const image = await tryReadImage(img_url, crop);
// Apply crop if defined
if (typeof crop == 'object' && [crop.x, crop.y, crop.width, crop.height].every(x => typeof x === 'number')) {
rawImg = rawImg.crop(crop.x, crop.y, crop.width, crop.height);
}
const image = await rawImg.cover(AVATAR_WIDTH, AVATAR_HEIGHT).getBufferAsync(jimp.MIME_PNG);
// Get the chunks // Get the chunks
const chunks = extract(image); const chunks = extract(image);
const tEXtChunks = chunks.filter(chunk => chunk.create_date === 'tEXt'); const tEXtChunks = chunks.filter(chunk => chunk.create_date === 'tEXt' || chunk.name === 'tEXt');
// Remove all existing tEXt chunks // Remove all existing tEXt chunks
for (let tEXtChunk of tEXtChunks) { for (let tEXtChunk of tEXtChunks) {
@@ -894,8 +887,6 @@ async function charaWrite(img_url, data, target_img, response = undefined, mes =
fs.writeFileSync(charactersPath + target_img + '.png', new Buffer.from(encode(chunks))); fs.writeFileSync(charactersPath + target_img + '.png', new Buffer.from(encode(chunks)));
if (response !== undefined) response.send(mes); if (response !== undefined) response.send(mes);
return true; return true;
} catch (err) { } catch (err) {
console.log(err); console.log(err);
if (response !== undefined) response.status(500).send(err); if (response !== undefined) response.status(500).send(err);
@@ -903,6 +894,24 @@ async function charaWrite(img_url, data, target_img, response = undefined, mes =
} }
} }
async function tryReadImage(img_url, crop) {
try {
let rawImg = await jimp.read(img_url);
// Apply crop if defined
if (typeof crop == 'object' && [crop.x, crop.y, crop.width, crop.height].every(x => typeof x === 'number')) {
rawImg = rawImg.crop(crop.x, crop.y, crop.width, crop.height);
}
const image = await rawImg.cover(AVATAR_WIDTH, AVATAR_HEIGHT).getBufferAsync(jimp.MIME_PNG);
return image;
}
// If it's an unsupported type of image (APNG) - just read the file as buffer
catch {
return fs.readFileSync(img_url);
}
}
async function charaRead(img_url, input_format) { async function charaRead(img_url, input_format) {
let format; let format;
if (input_format === undefined) { if (input_format === undefined) {
@@ -2341,12 +2350,21 @@ async function generateThumbnail(type, file) {
const imageSizes = { 'bg': [160, 90], 'avatar': [96, 144] }; const imageSizes = { 'bg': [160, 90], 'avatar': [96, 144] };
const mySize = imageSizes[type]; const mySize = imageSizes[type];
try {
let buffer;
try { try {
const image = await jimp.read(pathToOriginalFile); const image = await jimp.read(pathToOriginalFile);
const buffer = await image.cover(mySize[0], mySize[1]).quality(95).getBufferAsync(mime.lookup('jpg')); buffer = await image.cover(mySize[0], mySize[1]).quality(95).getBufferAsync(mime.lookup('jpg'));
}
catch (inner) {
console.warn(`Thumbnailer can not process the image: ${pathToOriginalFile}. Using original size`);
buffer = fs.readFileSync(pathToOriginalFile);
}
fs.writeFileSync(pathToCachedFile, buffer); fs.writeFileSync(pathToCachedFile, buffer);
} }
catch (err) { catch (outer) {
return null; return null;
} }