Redirects searching and loading of engine files at runtime to a specified directory or memory stream.
public OcrRuntimeFileCallback RuntimeFileCallback {get; set;}
Handler that can be used to redirect searching and loading of engine files at runtime to a specified directory or memory stream. The default value is null.
Important Note 1: This property is only supported by the OcrEngineType.LEAD engine.
Important Note 2: The LEAD Engine OCR Runtime file shipping with version 20 of LEADTOOLS does not support redirecting through a stream. Contact support@leadtools.com for instructions on how to obtain a copy of these files with streaming support.
The value of RuntimeFileCallback property is null by default. Therefore, locating and obtaining the runtime files necessary for the OCR engine to perform its operation is performed by either passing the name of the directory where these files reside to Startup as the startupParameters parameter, or relying on the automatic discovery of the engine files in the special folders as outlined in Startup.
The above technique is suitable for desktop-based applications that install on a physical path on the machine. There are situations where the above is not desired or possible:
The application may choose to download or extract runtime files on demand from internal resources embedded in the app or even external ones.
Some environments, such as Android, do not support obtaining a physical path to resources embedded in the application.
RuntimeFileCallback can be used to redirect the search and loading of OCR runtime files to support these types of applications.
An IOcrEngine instance will try to load one or more engine runtime files during its lifetime as follows:
In other words, for any LEAD.xyz.bin runtime file, IOcrEngine may request a check if the file exist one or more times and may request loading it one or more times. The order and frequency of these operations is internal to the engine.
The runtime files reside on disk files by default. Therefore, a request to check if a file exists is a simple call to the operating system File.Exists(fullPathToFile)
. If the file does exist, a request to load the file is made by calling File.OpenRead(fullPathToFile)
and then the content of the file is read. If the file does not exist, there will be no attempt to read it.
An application can use RuntimeFileCallback to intercept such calls and redirect checking for file existence and loading to a custom path or routine as follows:
Add a handler to IOcrEngine.RuntimeFileCallback before calling IOcrEngine.Startup. The order is important because the engine checks for a redirect during Startup
:
// Create a LEAD OCR Engine instance
IOcrEngine ocrEngine = OcrEngineManager.CreateEngine(OcrEngineType.LEAD)
// Add a runtime file redirect handler
ocrEngine.RuntimeFileCallback = runtimeFileCallbackHandler;
// Now start up the engine without passing a directory name to the runtime files.
// The handler will be called as many times as necessary to locate and load the OCR
// runtime files required by the engine
ocrEngine.Startup(null, null, null,
null /* startupParameters is null*/ );
Perform OCR operations as normal. The handler will be called as many times as necessary.
// OCR a TIF file and save it as PDF
// The handler can be called as many times as necessary to locate and load the OCR
// runtime files required by the engine for this operation
ocrEngine.AutoRecognizeManager.Run(
@"C:\LEADTOOLS23\Resources\Images\ocr1.tif",
@"C:\LEADTOOLS23\Resources\Images\out.pdf",
DocumentFormat.Pdf,
null,
null);
Optionally, remove the handler. This must be done after shutting the engine down but before disposing it
// Shutdown
ocrEngine.Shutdown();
// Remove the handler
ocrEngine.RuntimeFileCallback = null;
// Dispose the engine
ocrEngine.Dispose();
The handler is called with an instance of OcrRuntimeFile that describes the runtime file and the operation requested as follows:
Member | Description |
---|---|
FileName | Input only: The name of the OCR runtime file requested |
Guid | Input only: Unique identifier associated with this runtime file |
Mode | Input only: Operation to perform on the file, such check for its existence, opening it for reading or closing it |
FullPath | Output: Full path to where the file exists, if available |
Stream | Output: Stream containing the file data, if available |
Note that the engine will check if the callback has set a value in OcrRuntimeFile.FullPath first. If the value is null, then OcrRuntimeFile.Stream is used.
Important Note: The LEAD Engine OCR Runtime file shipping with version 20 of LEADTOOLS does not support redirecting through a stream. Contact support@Leadtools.com for instructions on how to obtain a copy of the files with streaming support.
This example shows how to use OcrRuntimeFileCallback to redirect LEAD OCR to load and locate files from a stream.
using Leadtools;
using Leadtools.Codecs;
using Leadtools.Ocr;
using Leadtools.Document.Writer;
public static void OcrRuntimeFileCallbackExample()
{
// This example assumes that some or all of the OCR runtime files are copied into "C:\MyDir" folder and simulates
// an environment where the runtime files can be obtained through helper methods HasResource and GetResourceStream.
// Create an OCR engine instance
IOcrEngine ocrEngine = OcrEngineManager.CreateEngine(OcrEngineType.LEAD);
// Install a OCR file runtime handler
ocrEngine.RuntimeFileCallback = MyRuntimeFileCallback;
// Startup the engine
ocrEngine.Startup(null, null, null,
null /* startupParameters is null*/);
// Perform OCR operation
ocrEngine.AutoRecognizeManager.Run(
@"C:\LEADTOOLS22\Resources\Images\ocr1.tif",
@"C:\LEADTOOLS22\Resources\Images\out.pdf",
DocumentFormat.Pdf,
null,
null);
// Shutdown
ocrEngine.Shutdown();
// Remove the handler
ocrEngine.RuntimeFileCallback = null;
// Dispose the engine
ocrEngine.Dispose();
}
private static RasterExceptionCode MyRuntimeFileCallback(IOcrEngine engine, OcrRuntimeFile runtimeFile)
{
// Called by the OCR engine for each runtime file operation
RasterExceptionCode result = RasterExceptionCode.Success;
// Check the operation:
switch (runtimeFile.Mode)
{
case OcrRuntimeFileMode.Exists:
Debug.WriteLine($"MyRuntimeFileCallback does '{runtimeFile.FileName}' exist");
// The engine is checking if a certain file exists, call our HasResource helper
if (!HasResource(runtimeFile.FileName))
result = RasterExceptionCode.FileNotFound;
break;
case OcrRuntimeFileMode.Open:
Debug.WriteLine($"MyRuntimeFileCallback open '{runtimeFile.FileName}'");
// The engine requested to open the file for reading, call our GetResourceStream helper
// and set the Stream property accordingly
runtimeFile.Stream = GetResourceStream(runtimeFile.FileName);
break;
case OcrRuntimeFileMode.Close:
Debug.WriteLine($"MyRuntimeFileCallback close '{runtimeFile.FileName}'");
// The engine requested to close the file after reading.
// Dispose our stream
runtimeFile.Stream.Dispose();
break;
}
return result;
}
private static bool HasResource(string resourceName)
{
// Do we have this resource?
// In our simulation, we will simply check if the file exist on disk
// In an Android application, this can check if a resource with this name was embedded
return System.IO.File.Exists(Path.Combine(@"C:\MyDir", resourceName));
}
private static Stream GetResourceStream(string resourceName)
{
// Get a stream that can read from resource
// In our simulation, we will simply check if the file exist on disk
// In an Android application, this can call the appropriate platform API to obtain
// a stream to the resource
return System.IO.File.OpenRead(Path.Combine(@"C:\MyDir", resourceName));
}