0a9588abb7
- Add pagination support to findAll (page, limit query params) - Add findByTemplateId method to service - Add GET /by-template/:templateId endpoint to controller - Service already includes CRUD for QuestionBank and QuestionBankItem
81 lines
2.2 KiB
TypeScript
81 lines
2.2 KiB
TypeScript
import { Injectable, Logger } from '@nestjs/common';
|
|
import { createWorker, Worker } from 'tesseract.js';
|
|
import { I18nService } from '../i18n/i18n.service';
|
|
|
|
@Injectable()
|
|
export class OcrService {
|
|
private readonly logger = new Logger(OcrService.name);
|
|
|
|
constructor(private readonly i18n: I18nService) {}
|
|
|
|
async extractTextFromImage(imageBuffer: Buffer): Promise<string> {
|
|
this.logger.log(
|
|
`Starting OCR extraction from image (${imageBuffer.length} bytes)...`,
|
|
);
|
|
|
|
// Create worker for this request to ensure stability
|
|
let worker: any = null;
|
|
try {
|
|
worker = await createWorker('chi_sim+eng+jpn');
|
|
|
|
const {
|
|
data: { text },
|
|
} = await worker.recognize(imageBuffer);
|
|
this.logger.log(
|
|
`OCR extraction completed. ${text.length} characters extracted.`,
|
|
);
|
|
|
|
if (text.length === 0) {
|
|
this.logger.warn('OCR returned empty text.');
|
|
}
|
|
|
|
await worker.terminate();
|
|
return text.trim();
|
|
} catch (error) {
|
|
this.logger.error(`OCR text extraction failed: ${error.message}`);
|
|
if (worker) {
|
|
try {
|
|
await worker.terminate();
|
|
} catch (e) {}
|
|
}
|
|
throw new Error(
|
|
this.i18n.formatMessage('ocrFailed', { message: error.message }),
|
|
);
|
|
}
|
|
}
|
|
|
|
async extractTextWithConfidence(imageBuffer: Buffer): Promise<{
|
|
text: string;
|
|
confidence: number;
|
|
}> {
|
|
this.logger.log(
|
|
`Starting OCR extraction with confidence (${imageBuffer.length} bytes)...`,
|
|
);
|
|
|
|
let worker: any = null;
|
|
try {
|
|
worker = await createWorker('chi_sim+eng+jpn');
|
|
const { data } = await worker.recognize(imageBuffer);
|
|
this.logger.log(
|
|
`OCR extraction completed. Confidence: ${data.confidence}%`,
|
|
);
|
|
|
|
await worker.terminate();
|
|
return {
|
|
text: data.text.trim(),
|
|
confidence: data.confidence,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`OCR text extraction failed: ${error.message}`);
|
|
if (worker) {
|
|
try {
|
|
await worker.terminate();
|
|
} catch (e) {}
|
|
}
|
|
throw new Error(
|
|
this.i18n.formatMessage('ocrFailed', { message: error.message }),
|
|
);
|
|
}
|
|
}
|
|
}
|