mirror of
https://github.com/zadam/trilium.git
synced 2025-12-06 15:34:26 +01:00
feat(ocr): automatically process images
This commit is contained in:
parent
08ca86c68a
commit
72cea245f1
@ -140,7 +140,8 @@ eventService.subscribe(eventService.ENTITY_CREATED, ({ entityName, entity }) =>
|
|||||||
} else if (entityName === "notes") {
|
} else if (entityName === "notes") {
|
||||||
runAttachedRelations(entity, "runOnNoteCreation", entity);
|
runAttachedRelations(entity, "runOnNoteCreation", entity);
|
||||||
|
|
||||||
// Automatically process OCR for file notes if OCR is enabled
|
// Note: OCR processing for images is now handled in image.ts during image processing
|
||||||
|
// OCR processing for files remains here since they don't go through image processing
|
||||||
if (entity.type === 'file' && ocrService.isOCREnabled()) {
|
if (entity.type === 'file' && ocrService.isOCREnabled()) {
|
||||||
// Check if the file MIME type is supported by any OCR processor
|
// Check if the file MIME type is supported by any OCR processor
|
||||||
const supportedMimeTypes = ocrService.getAllSupportedMimeTypes();
|
const supportedMimeTypes = ocrService.getAllSupportedMimeTypes();
|
||||||
|
|||||||
@ -12,8 +12,9 @@ import sanitizeFilename from "sanitize-filename";
|
|||||||
import isSvg from "is-svg";
|
import isSvg from "is-svg";
|
||||||
import isAnimated from "is-animated";
|
import isAnimated from "is-animated";
|
||||||
import htmlSanitizer from "./html_sanitizer.js";
|
import htmlSanitizer from "./html_sanitizer.js";
|
||||||
|
import ocrService, { type OCRResult } from "./ocr/ocr_service.js";
|
||||||
|
|
||||||
async function processImage(uploadBuffer: Buffer, originalName: string, shrinkImageSwitch: boolean) {
|
async function processImage(uploadBuffer: Buffer, originalName: string, shrinkImageSwitch: boolean, noteId?: string) {
|
||||||
const compressImages = optionService.getOptionBool("compressImages");
|
const compressImages = optionService.getOptionBool("compressImages");
|
||||||
const origImageFormat = await getImageType(uploadBuffer);
|
const origImageFormat = await getImageType(uploadBuffer);
|
||||||
|
|
||||||
@ -24,6 +25,24 @@ async function processImage(uploadBuffer: Buffer, originalName: string, shrinkIm
|
|||||||
shrinkImageSwitch = false;
|
shrinkImageSwitch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Process OCR on the original (uncompressed) image for best quality
|
||||||
|
let ocrResult: OCRResult | null = null;
|
||||||
|
if (noteId && ocrService.isOCREnabled() && origImageFormat) {
|
||||||
|
const imageMime = getImageMimeFromExtension(origImageFormat.ext);
|
||||||
|
const supportedMimeTypes = ocrService.getAllSupportedMimeTypes();
|
||||||
|
|
||||||
|
if (supportedMimeTypes.includes(imageMime)) {
|
||||||
|
try {
|
||||||
|
ocrResult = await ocrService.extractTextFromFile(uploadBuffer, imageMime);
|
||||||
|
if (ocrResult) {
|
||||||
|
log.info(`Successfully processed OCR for image ${noteId} (${originalName})`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
log.error(`Failed to process OCR for image ${noteId}: ${error}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let finalImageBuffer;
|
let finalImageBuffer;
|
||||||
let imageFormat;
|
let imageFormat;
|
||||||
|
|
||||||
@ -39,7 +58,8 @@ async function processImage(uploadBuffer: Buffer, originalName: string, shrinkIm
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
buffer: finalImageBuffer,
|
buffer: finalImageBuffer,
|
||||||
imageFormat
|
imageFormat,
|
||||||
|
ocrResult
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,12 +92,17 @@ function updateImage(noteId: string, uploadBuffer: Buffer, originalName: string)
|
|||||||
note.setLabel("originalFileName", originalName);
|
note.setLabel("originalFileName", originalName);
|
||||||
|
|
||||||
// resizing images asynchronously since JIMP does not support sync operation
|
// resizing images asynchronously since JIMP does not support sync operation
|
||||||
processImage(uploadBuffer, originalName, true).then(({ buffer, imageFormat }) => {
|
processImage(uploadBuffer, originalName, true, noteId).then(({ buffer, imageFormat, ocrResult }) => {
|
||||||
sql.transactional(() => {
|
sql.transactional(() => {
|
||||||
note.mime = getImageMimeFromExtension(imageFormat.ext);
|
note.mime = getImageMimeFromExtension(imageFormat.ext);
|
||||||
note.save();
|
note.save();
|
||||||
|
|
||||||
note.setContent(buffer);
|
note.setContent(buffer);
|
||||||
|
|
||||||
|
// Store OCR result if available
|
||||||
|
if (ocrResult && note.blobId) {
|
||||||
|
ocrService.storeOCRResult(note.blobId, ocrResult);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -108,7 +133,7 @@ function saveImage(parentNoteId: string, uploadBuffer: Buffer, originalName: str
|
|||||||
note.addLabel("originalFileName", originalName);
|
note.addLabel("originalFileName", originalName);
|
||||||
|
|
||||||
// resizing images asynchronously since JIMP does not support sync operation
|
// resizing images asynchronously since JIMP does not support sync operation
|
||||||
processImage(uploadBuffer, originalName, shrinkImageSwitch).then(({ buffer, imageFormat }) => {
|
processImage(uploadBuffer, originalName, shrinkImageSwitch, note.noteId).then(({ buffer, imageFormat, ocrResult }) => {
|
||||||
sql.transactional(() => {
|
sql.transactional(() => {
|
||||||
note.mime = getImageMimeFromExtension(imageFormat.ext);
|
note.mime = getImageMimeFromExtension(imageFormat.ext);
|
||||||
|
|
||||||
@ -120,6 +145,11 @@ function saveImage(parentNoteId: string, uploadBuffer: Buffer, originalName: str
|
|||||||
}
|
}
|
||||||
|
|
||||||
note.setContent(buffer, { forceSave: true });
|
note.setContent(buffer, { forceSave: true });
|
||||||
|
|
||||||
|
// Store OCR result if available
|
||||||
|
if (ocrResult && note.blobId) {
|
||||||
|
ocrService.storeOCRResult(note.blobId, ocrResult);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -159,7 +189,7 @@ function saveImageToAttachment(noteId: string, uploadBuffer: Buffer, originalNam
|
|||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
// resizing images asynchronously since JIMP does not support sync operation
|
// resizing images asynchronously since JIMP does not support sync operation
|
||||||
processImage(uploadBuffer, originalName, !!shrinkImageSwitch).then(({ buffer, imageFormat }) => {
|
processImage(uploadBuffer, originalName, !!shrinkImageSwitch, attachment.attachmentId).then(({ buffer, imageFormat, ocrResult }) => {
|
||||||
sql.transactional(() => {
|
sql.transactional(() => {
|
||||||
// re-read, might be changed in the meantime
|
// re-read, might be changed in the meantime
|
||||||
if (!attachment.attachmentId) {
|
if (!attachment.attachmentId) {
|
||||||
@ -175,6 +205,11 @@ function saveImageToAttachment(noteId: string, uploadBuffer: Buffer, originalNam
|
|||||||
}
|
}
|
||||||
|
|
||||||
attachment.setContent(buffer, { forceSave: true });
|
attachment.setContent(buffer, { forceSave: true });
|
||||||
|
|
||||||
|
// Store OCR result if available
|
||||||
|
if (ocrResult && attachment.blobId) {
|
||||||
|
ocrService.storeOCRResult(attachment.blobId, ocrResult);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user