/
viktorphp
/
back-socket
Обзор
Документация
Войти
/
viktorphp
/
back-socket
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/services/ocr/ocr.service.ts
122 строки
5 KB
Иванов Виктор Евгеньевич
feature-diary: добавить функционал дневника
11 апр 2026, 11:13
11 апр 2026, 11:13
8167a94
Код
Авторство
О чём код?
import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { HttpService } from '@nestjs/axios'; import { firstValueFrom } from 'rxjs'; /** * Поддерживаемые Yandex Vision OCR модели распознавания. * - page: распознавание печатного текста (документы, фото текста) * - handwritten: рукописный текст */ type OcrModel = 'page' | 'handwritten'; /** * OcrService — сервис для распознавания текста через Yandex Vision OCR API. * * Документация API: https://yandex.cloud/ru/docs/vision/ocr/api-ref/ * * Принцип работы: * 1. Файл (изображение или PDF) передаётся в base64 * 2. Отправляем POST-запрос к API с указанием MIME-типа и модели * 3. API возвращает распознанный текст блоками — мы собираем их в одну строку */ @Injectable() export class OcrService { // Эндпоинт Yandex Vision OCR API private readonly apiUrl = 'https://ocr.api.cloud.yandex.net/ocr/v1/recognizeText'; private readonly apiKey: string; constructor( private readonly configService: ConfigService, private readonly httpService: HttpService, ) { this.apiKey = this.configService.get<string>('vision.apiKey'); } /** * Распознаёт текст на изображении или в PDF-файле. * * @param fileBuffer - Содержимое файла в виде Buffer * @param mimeType - MIME-тип: 'image/jpeg', 'image/png', 'application/pdf' и т.д. * @returns Распознанный текст одной строкой (блоки объединены через \n) * @throws Error если API вернул ошибку или не удалось распознать текст */ async recognizeText(fileBuffer: Buffer, mimeType: string): Promise<string> { // Кодируем файл в base64 — именно в таком формате ожидает API const base64Content = fileBuffer.toString('base64'); // Определяем модель распознавания в зависимости от MIME-типа. // Для PDF используем модель 'page' (печатный текст). // При необходимости модель можно сделать параметром метода. const model: OcrModel = 'page'; // Формируем тело запроса согласно документации Yandex Vision OCR const requestBody = { mimeType, // тип файла: image/jpeg, application/pdf и т.д. languageCodes: ['ru', 'en'], // языки для распознавания model, // модель: page (печать) или handwritten (рукопись) content: base64Content, // содержимое файла в base64 }; // Отправляем запрос к API с API-ключом в заголовке Authorization const response = await firstValueFrom( this.httpService.post(this.apiUrl, requestBody, { headers: { Authorization: `Api-Key ${this.apiKey}`, 'Content-Type': 'application/json', }, }), ); // Извлекаем распознанный текст из ответа. // Структура ответа API: // result.textAnnotation.blocks[] → lines[] → words[] → text // Либо можно использовать result.textAnnotation.fullText (если доступно) const textAnnotation = response.data?.result?.textAnnotation; if (!textAnnotation) { throw new Error('Yandex Vision API не вернул результат распознавания'); } // Если API вернул готовое поле fullText — используем его if (textAnnotation.fullText) { return textAnnotation.fullText; } // Иначе собираем текст из блоков вручную const blocks: string[] = (textAnnotation.blocks ?? []).map((block: any) => { const lines: string[] = (block.lines ?? []).map((line: any) => { const words: string[] = (line.words ?? []).map( (word: any) => word.text ?? '', ); return words.join(' '); }); return lines.join('\n'); }); return blocks.join('\n\n'); } /** * Проверяет, поддерживает ли данный MIME-тип OCR-распознавание. * Yandex Vision OCR работает с изображениями (jpeg, png, gif, bmp, tiff, webp) и PDF. * * @param mimeType - MIME-тип файла * @returns true если файл можно отправить на распознавание */ isSupportedMimeType(mimeType: string): boolean { const supported = [ 'image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/bmp', 'image/tiff', 'image/webp', 'application/pdf', ]; return supported.includes(mimeType.toLowerCase()); } }