fix image resizing after save/update/import

This commit is contained in:
zadam 2020-07-28 00:26:47 +02:00
parent c9cbc2db02
commit a7b62b30cb
2 changed files with 27 additions and 19 deletions

View File

@ -5,13 +5,14 @@ const log = require('./log');
const protectedSessionService = require('./protected_session'); const protectedSessionService = require('./protected_session');
const noteService = require('./notes'); const noteService = require('./notes');
const optionService = require('./options'); const optionService = require('./options');
const sql = require('./sql');
const jimp = require('jimp'); const jimp = require('jimp');
const imageType = require('image-type'); const imageType = require('image-type');
const sanitizeFilename = require('sanitize-filename'); const sanitizeFilename = require('sanitize-filename');
const noteRevisionService = require('./note_revisions.js'); const noteRevisionService = require('./note_revisions.js');
const isSvg = require('is-svg'); const isSvg = require('is-svg');
function processImage(uploadBuffer, originalName, shrinkImageSwitch) { async function processImage(uploadBuffer, originalName, shrinkImageSwitch) {
const origImageFormat = getImageType(uploadBuffer); const origImageFormat = getImageType(uploadBuffer);
if (origImageFormat && ["webp", "svg"].includes(origImageFormat.ext)) { if (origImageFormat && ["webp", "svg"].includes(origImageFormat.ext)) {
@ -19,7 +20,7 @@ function processImage(uploadBuffer, originalName, shrinkImageSwitch) {
shrinkImageSwitch = false; shrinkImageSwitch = false;
} }
const finalImageBuffer = shrinkImageSwitch ? shrinkImage(uploadBuffer) : uploadBuffer; const finalImageBuffer = shrinkImageSwitch ? await shrinkImage(uploadBuffer) : uploadBuffer;
const imageFormat = getImageType(finalImageBuffer); const imageFormat = getImageType(finalImageBuffer);
@ -49,26 +50,25 @@ function getImageMimeFromExtension(ext) {
function updateImage(noteId, uploadBuffer, originalName) { function updateImage(noteId, uploadBuffer, originalName) {
log.info(`Updating image ${noteId}: ${originalName}`); log.info(`Updating image ${noteId}: ${originalName}`);
const {buffer, imageFormat} = processImage(uploadBuffer, originalName, true);
const note = repository.getNote(noteId); const note = repository.getNote(noteId);
noteRevisionService.createNoteRevision(note); noteRevisionService.createNoteRevision(note);
noteRevisionService.protectNoteRevisions(note);
note.mime = getImageMimeFromExtension(imageFormat.ext);
note.setContent(buffer);
note.setLabel('originalFileName', originalName); note.setLabel('originalFileName', originalName);
noteRevisionService.protectNoteRevisions(note); // resizing images asynchronously since JIMP does not support sync operation
processImage(uploadBuffer, originalName, true).then(({buffer, imageFormat}) => {
sql.transactional(() => {
note.mime = getImageMimeFromExtension(imageFormat.ext);
note.setContent(buffer);
})
});
} }
function saveImage(parentNoteId, uploadBuffer, originalName, shrinkImageSwitch) { function saveImage(parentNoteId, uploadBuffer, originalName, shrinkImageSwitch) {
log.info(`Saving image ${originalName}`); log.info(`Saving image ${originalName}`);
const {buffer, imageFormat} = processImage(uploadBuffer, originalName, shrinkImageSwitch);
const fileName = sanitizeFilename(originalName); const fileName = sanitizeFilename(originalName);
const parentNote = repository.getNote(parentNoteId); const parentNote = repository.getNote(parentNoteId);
@ -76,14 +76,22 @@ function saveImage(parentNoteId, uploadBuffer, originalName, shrinkImageSwitch)
const {note} = noteService.createNewNote({ const {note} = noteService.createNewNote({
parentNoteId, parentNoteId,
title: fileName, title: fileName,
content: buffer,
type: 'image', type: 'image',
mime: getImageMimeFromExtension(imageFormat.ext), mime: 'unknown',
content: '',
isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable() isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable()
}); });
note.addLabel('originalFileName', originalName); note.addLabel('originalFileName', originalName);
// resizing images asynchronously since JIMP does not support sync operation
processImage(uploadBuffer, originalName, shrinkImageSwitch).then(({buffer, imageFormat}) => {
sql.transactional(() => {
note.mime = getImageMimeFromExtension(imageFormat.ext);
note.setContent(buffer);
})
});
return { return {
fileName, fileName,
note, note,
@ -92,9 +100,9 @@ function saveImage(parentNoteId, uploadBuffer, originalName, shrinkImageSwitch)
}; };
} }
function shrinkImage(buffer) { async function shrinkImage(buffer) {
const jpegQuality = optionService.getOptionInt('imageJpegQuality'); const jpegQuality = optionService.getOptionInt('imageJpegQuality');
let finalImageBuffer = resize(buffer, jpegQuality); let finalImageBuffer = await resize(buffer, jpegQuality);
// if resizing & shrinking did not help with size then save the original // if resizing & shrinking did not help with size then save the original
// (can happen when e.g. resizing PNG into JPEG) // (can happen when e.g. resizing PNG into JPEG)
@ -105,10 +113,10 @@ function shrinkImage(buffer) {
return finalImageBuffer; return finalImageBuffer;
} }
function resize(buffer, quality) { async function resize(buffer, quality) {
const imageMaxWidthHeight = optionService.getOptionInt('imageMaxWidthHeight'); const imageMaxWidthHeight = optionService.getOptionInt('imageMaxWidthHeight');
const image = jimp.read(buffer); const image = await jimp.read(buffer);
if (image.bitmap.width > image.bitmap.height && image.bitmap.width > imageMaxWidthHeight) { if (image.bitmap.width > image.bitmap.height && image.bitmap.width > imageMaxWidthHeight) {
image.resize(imageMaxWidthHeight, jimp.AUTO); image.resize(imageMaxWidthHeight, jimp.AUTO);
@ -122,7 +130,7 @@ function resize(buffer, quality) {
// when converting PNG to JPG we lose alpha channel, this is replaced by white to match Trilium white background // when converting PNG to JPG we lose alpha channel, this is replaced by white to match Trilium white background
image.background(0xFFFFFFFF); image.background(0xFFFFFFFF);
return image.getBufferAsync(jimp.MIME_JPEG); return await image.getBufferAsync(jimp.MIME_JPEG);
} }
module.exports = { module.exports = {

View File

@ -298,7 +298,7 @@ function downloadImages(noteId, content) {
const imageBuffer = Buffer.from(imageBase64, 'base64'); const imageBuffer = Buffer.from(imageBase64, 'base64');
const imageService = require('../services/image'); const imageService = require('../services/image');
const {note} = await imageService.saveImage(noteId, imageBuffer, "inline image", true); const {note} = imageService.saveImage(noteId, imageBuffer, "inline image", true);
content = content.substr(0, match.index) content = content.substr(0, match.index)
+ `<img src="api/images/${note.noteId}/${note.title}"` + `<img src="api/images/${note.noteId}/${note.title}"`