From 80f49aecd74ab5ed48158c87136f875c3e2c4e15 Mon Sep 17 00:00:00 2001 From: kangfenmao Date: Tue, 2 Sep 2025 02:29:24 +0800 Subject: [PATCH] feat(ocr): enhance OCR service for Linux compatibility and update image processing - Added conditional registration of the system OCR service for non-Linux platforms. - Updated SystemOcrService to handle Linux by returning an empty text response. - Modified image preprocessing to dynamically require the 'sharp' library, improving compatibility and performance. - Included additional files in the electron-builder configuration for packaging. --- electron-builder.yml | 1 + src/main/services/ocr/OcrService.ts | 8 ++++++-- src/main/services/ocr/builtin/SystemOcrService.ts | 11 ++++++----- src/main/utils/ocr.ts | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/electron-builder.yml b/electron-builder.yml index 1f6dce36b..6683c22ff 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -62,6 +62,7 @@ files: asarUnpack: - resources/** - '**/*.{metal,exp,lib}' + - 'node_modules/@img/sharp-libvips-*/**' win: executableName: Cherry Studio artifactName: ${productName}-${version}-${arch}-setup.${ext} diff --git a/src/main/services/ocr/OcrService.ts b/src/main/services/ocr/OcrService.ts index 0d7383a24..20ea20122 100644 --- a/src/main/services/ocr/OcrService.ts +++ b/src/main/services/ocr/OcrService.ts @@ -1,7 +1,7 @@ import { loggerService } from '@logger' +import { isLinux } from '@main/constant' import { BuiltinOcrProviderIds, OcrHandler, OcrProvider, OcrResult, SupportedOcrFile } from '@types' -import { systemOcrService } from './builtin/SystemOcrService' import { tesseractService } from './builtin/TesseractService' const logger = loggerService.withContext('OcrService') @@ -33,4 +33,8 @@ export const ocrService = new OcrService() // Register built-in providers ocrService.register(BuiltinOcrProviderIds.tesseract, tesseractService.ocr.bind(tesseractService)) -ocrService.register(BuiltinOcrProviderIds.system, systemOcrService.ocr.bind(systemOcrService)) + +if (!isLinux) { + const { systemOcrService } = require('./builtin/SystemOcrService') + ocrService.register(BuiltinOcrProviderIds.system, systemOcrService.ocr.bind(systemOcrService)) +} diff --git a/src/main/services/ocr/builtin/SystemOcrService.ts b/src/main/services/ocr/builtin/SystemOcrService.ts index cda52bfec..f6fcfe32a 100644 --- a/src/main/services/ocr/builtin/SystemOcrService.ts +++ b/src/main/services/ocr/builtin/SystemOcrService.ts @@ -1,6 +1,5 @@ -import { isMac, isWin } from '@main/constant' +import { isLinux, isWin } from '@main/constant' import { loadOcrImage } from '@main/utils/ocr' -import { OcrAccuracy, recognize } from '@napi-rs/system-ocr' import { ImageFileMetadata, isImageFileMetadata as isImageFileMetadata, @@ -15,12 +14,14 @@ import { OcrBaseService } from './OcrBaseService' export class SystemOcrService extends OcrBaseService { constructor() { super() - if (!isWin && !isMac) { - throw new Error('System OCR is only supported on Windows and macOS') - } } private async ocrImage(file: ImageFileMetadata, options?: OcrSystemConfig): Promise { + if (isLinux) { + return { text: '' } + } + + const { OcrAccuracy, recognize } = require('@napi-rs/system-ocr') const buffer = await loadOcrImage(file) const langs = isWin ? options?.langs : undefined const result = await recognize(buffer, OcrAccuracy.Accurate, langs) diff --git a/src/main/utils/ocr.ts b/src/main/utils/ocr.ts index 446fbe63d..d94fb002d 100644 --- a/src/main/utils/ocr.ts +++ b/src/main/utils/ocr.ts @@ -1,8 +1,8 @@ import { ImageFileMetadata } from '@types' import { readFile } from 'fs/promises' -import sharp from 'sharp' const preprocessImage = async (buffer: Buffer): Promise => { + const sharp = require('sharp') return sharp(buffer) .grayscale() // 转为灰度 .normalize()