import { Injectable, Logger } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import axios from 'axios'; @Injectable() export class OcrService { private readonly logger = new Logger(OcrService.name); private readonly ollamaUrl: string; private readonly ollamaModel: string; constructor(private readonly configService: ConfigService) { this.ollamaUrl = this.configService.get( 'OLLAMA_URL', 'http://localhost:11434', ); this.ollamaModel = this.configService.get('OLLAMA_MODEL', 'llava'); } /** * Sendet ein Bild an Ollama Vision und erhält den Inhalt als Markdown. */ async extractTextAsMarkdown(imageBuffer: Buffer): Promise { const base64Image = imageBuffer.toString('base64'); const prompt = `Analysiere dieses Dokument und extrahiere den gesamten Text. Gib den Text als sauberes Markdown zurück, behalte die Struktur bei (Überschriften, Tabellen, Listen). Antworte nur mit dem extrahierten Markdown-Text, keine Erklärungen.`; try { const response = await axios.post( `${this.ollamaUrl}/api/generate`, { model: this.ollamaModel, prompt, images: [base64Image], stream: false, options: { temperature: 0.1, }, }, { timeout: 120000 }, ); const markdown = response.data.response?.trim() ?? ''; this.logger.log( `OCR abgeschlossen: ${markdown.length} Zeichen extrahiert`, ); return markdown; } catch (error: any) { this.logger.error(`Ollama OCR fehlgeschlagen: ${error.message}`); throw error; } } }