UNPKG

ppu-paddle-ocr

Version:

Lightweight, probably the fastest PaddleOCR SDK in TypeScript. Runs anywhere JavaScript runs: Node.js, Bun, Deno, mobile react-native, web browsers, and browser extensions. Docker & CLI supported. The official SDK is browser-only. Accurate text detection

5 lines 5.78 kB
import*as ort from"onnxruntime-react-native";import{BasePaddleOcrService}from"../core/base-paddle-ocr.service.js";import{createSessionWithFallback}from"../core/session-factory.js";import{DEFAULT_MODEL_URLS}from"../model-catalogue.js";import{fetchArrayBufferWithRetry,parseDictionary}from"../utils.js";import{DetectionService}from"./detection.service.mobile.js";import{getDefaultMobileExecutionProviders,MobilePlatformProvider}from"./platform.mobile.js";import{RecognitionService}from"./recognition.service.mobile.js";let DEFAULT_MOBILE_SESSION_OPTIONS={graphOptimizationLevel:"all"};export class PaddleOcrService extends BasePaddleOcrService{constructor(options){super(new MobilePlatformProvider,options);if(this.options.session===undefined||Object.keys(this.options.session).length===0){this.options.session=DEFAULT_MOBILE_SESSION_OPTIONS}}async initSessions(){throw new Error("Initialization is handled proactively in PaddleOcrService. Call initialize() instead.")}async _loadResource(source,defaultUrl){if(source instanceof ArrayBuffer){this.log("Loading resource from ArrayBuffer");return source}let sourceUrl=typeof source==="string"?source:defaultUrl;this.log(`Fetching resource from URL: ${sourceUrl}`);return fetchArrayBufferWithRetry(sourceUrl)}_resolveSessionExecutionProviders(){let current=this.options.session??{};if(current.executionProviders&&current.executionProviders.length>0){this.log(`Using user-provided executionProviders: ${JSON.stringify(current.executionProviders)}`);return}let providers=getDefaultMobileExecutionProviders();this.options.session={...current,executionProviders:providers};this.log(`Resolved executionProviders: ${JSON.stringify(providers)}`)}async _createSession(modelData){return createSessionWithFallback(ort,modelData,this.options.session,(msg)=>console.warn(`[PaddleOcrService] ${msg}`),(next)=>this.options.session=next)}async initialize(){try{this.log("Initializing PaddleOcrService (Mobile)...");this._resolveSessionExecutionProviders();const[detModelBuffer,recModelBuffer,dictBuffer]=await Promise.all([this._loadResource(this.options.model?.detection,DEFAULT_MODEL_URLS.detection),this._loadResource(this.options.model?.recognition,DEFAULT_MODEL_URLS.recognition),this._loadResource(this.options.model?.charactersDictionary,DEFAULT_MODEL_URLS.charactersDictionary)]);const[detectionSession,recognitionSession]=await Promise.all([this._createSession(new Uint8Array(detModelBuffer)),this._createSession(new Uint8Array(recModelBuffer))]);this.detectionSession=detectionSession;this.recognitionSession=recognitionSession;if(this.options.model)this.options.model.detection=detModelBuffer;if(this.options.model)this.options.model.recognition=recModelBuffer;this.log(`Detection ONNX model loaded successfully input: ${detectionSession.inputNames} output: ${detectionSession.outputNames}`);this.log(`Recognition ONNX model loaded successfully input: ${recognitionSession.inputNames} output: ${recognitionSession.outputNames}`);let charactersDictionary=parseDictionary(dictBuffer);if(charactersDictionary.length===0){throw new Error("Character dictionary is empty or could not be loaded.")}if(this.options.model)this.options.model.charactersDictionary=dictBuffer;if(this.options.recognition)this.options.recognition.charactersDictionary=charactersDictionary;this.log(`Character dictionary loaded with ${charactersDictionary.length} entries.`);this.detector=new DetectionService(detectionSession,this.options.detection,this.options.debugging);this.recognitor=new RecognitionService(recognitionSession,this.options.recognition,this.options.debugging);if(this.options.model)this.options.model.detection=undefined;if(this.options.model)this.options.model.recognition=undefined}catch(error){console.error("Failed to initialize PaddleOcrService Mobile:",error);throw error}}isInitialized(){return this.detectionSession!==null&&this.recognitionSession!==null}async changeDetectionModel(model){this.log("Changing detection model...");let modelBuffer=await this._loadResource(model,DEFAULT_MODEL_URLS.detection);await this.detectionSession?.release();this.detectionSession=await this._createSession(new Uint8Array(modelBuffer));this.detector=new DetectionService(this.detectionSession,this.options.detection,this.options.debugging);if(this.options.model)this.options.model.detection=modelBuffer;this.log("Detection model changed successfully.")}async changeRecognitionModel(model){this.log("Changing recognition model...");let modelBuffer=await this._loadResource(model,DEFAULT_MODEL_URLS.recognition);await this.recognitionSession?.release();this.recognitionSession=await this._createSession(new Uint8Array(modelBuffer));this.recognitor=new RecognitionService(this.recognitionSession,this.options.recognition,this.options.debugging);if(this.options.model)this.options.model.recognition=modelBuffer;this.log("Recognition model changed successfully.")}async changeTextDictionary(dictionary){this.log("Changing text dictionary...");let dictBuffer=await this._loadResource(dictionary,DEFAULT_MODEL_URLS.charactersDictionary);let charactersDictionary=parseDictionary(dictBuffer);if(charactersDictionary.length===0){throw new Error("Character dictionary is empty or could not be loaded.")}if(this.options.model)this.options.model.charactersDictionary=dictBuffer;if(this.options.recognition)this.options.recognition.charactersDictionary=charactersDictionary;this.log(`Character dictionary changed successfully with ${charactersDictionary.length} entries.`)}async recognize(image,options){return super.recognize(image,options)}async destroy(){await this.detectionSession?.release();await this.recognitionSession?.release();this.detectionSession=null;this.recognitionSession=null;this.detector=null;this.recognitor=null}}export default PaddleOcrService;