I am trying to implement Tesseract in Xamarin.Forms (Android) but I think, the solution is fine in any android based language.
I have the following exception
“System.Reflection.TargetInvocationException: Exception has been
thrown by the target of an invocation. —>
System.ArgumentNullException: Value cannot be null.nParameter name:
pathn at System.IO.Path.InsecureGetFullPath (System.String path)
[0x00003] in
/Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/corlib/System.IO/Path.cs:369
n at System.IO.Path.GetFullPath (System.String path) [0x00000] in
/Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/corlib/System.IO/Path.cs:288
n at InteropDotNet.LibraryLoader.CheckCurrentAppDomain
(System.String fileName, System.String platformName) [0x0000a] in
<34588703652c4d2782e7c04fa8ce17a8>:0 n at
InteropDotNet.LibraryLoader.LoadLibrary (System.String fileName,
System.String platformName) [0x00076] in
<34588703652c4d2782e7c04fa8ce17a8>:0 n at
InteropRuntimeImplementer.LeptonicaApiSignaturesInstance.LeptonicaApiSignaturesImplementation..ctor
(InteropDotNet.LibraryLoader loader) [0x00006] in
<93eaf1981dc541f287b07be199bb8012>:0 n at (wrapper
managed-to-native)
System.Reflection.RuntimeConstructorInfo.InternalInvoke(System.Reflection.RuntimeConstructorInfo,object,object[],System.Exception&)n
at System.Reflection.RuntimeConstructorInfo.InternalInvoke
(System.Object obj, System.Object[] parameters, System.Boolean
wrapExceptions) [0x00005] in
/Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/corlib/System.Reflection/RuntimeMethodInfo.cs:936
n — End of inner exception stack trace —n at
System.Reflection.RuntimeConstructorInfo.InternalInvoke (System.Object
obj, System.Object[] parameters, System.Boolean wrapExceptions)
[0x00018] in
/Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/corlib/System.Reflection/RuntimeMethodInfo.cs:944
n at System.Reflection.RuntimeConstructorInfo.DoInvoke
(System.Object obj, System.Reflection.BindingFlags invokeAttr,
System.Reflection.Binder binder, System.Object[] parameters,
System.Globalization.CultureInfo culture) [0x00086] in
/Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/corlib/System.Reflection/RuntimeMethodInfo.cs:926
n at System.Reflection.RuntimeConstructorInfo.Invoke
(System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder
binder, System.Object[] parameters, System.Globalization.CultureInfo
culture) [0x00000] in
/Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/corlib/System.Reflection/RuntimeMethodInfo.cs:960
n at System.RuntimeType.CreateInstanceImpl
(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder
binder, System.Object[] args, System.Globalization.CultureInfo
culture, System.Object[] activationAttributes,
System.Threading.StackCrawlMark& stackMark) [0x0022b] in
/Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/rttype.cs:5535
n at System.Activator.CreateInstance (System.Type type,
System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder
binder, System.Object[] args, System.Globalization.CultureInfo
culture, System.Object[] activationAttributes) [0x000b5] in
/Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/activator.cs:107
n at System.Activator.CreateInstance (System.Type type,
System.Object[] args) [0x00000] in
/Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/activator.cs:112
n at InteropDotNet.InteropRuntimeImplementer.CreateInstance[T] ()
[0x000c9] in <34588703652c4d2782e7c04fa8ce17a8>:0 n at
Tesseract.Interop.LeptonicaApi.Initialize () [0x00007] in
<34588703652c4d2782e7c04fa8ce17a8>:0 n at
Tesseract.Interop.TessApi.Initialize () [0x00007] in
<34588703652c4d2782e7c04fa8ce17a8>:0 n at
Tesseract.Interop.TessApi.get_Native () [0x00007] in
<34588703652c4d2782e7c04fa8ce17a8>:0 n at
Tesseract.TesseractEngine..ctor (System.String datapath, System.String
language, Tesseract.EngineMode engineMode,
System.Collections.Generic.IEnumerable1[T] configFiles,
System.Collections.Generic.IDictionary2[TKey,TValue] initialOptions,
System.Boolean setOnlyNonDebugVariables) [0x00018] in
<34588703652c4d2782e7c04fa8ce17a8>:0 n at
Tesseract.TesseractEngine..ctor (System.String datapath, System.String
language, Tesseract.EngineMode engineMode) [0x0000f] in
<34588703652c4d2782e7c04fa8ce17a8>:0 n at
LedOcr.Droid.AndroidOcrProcessor.PerformOcr (System.String imagePath)
[0x001da] in
C:userProjectsTempLedOcrLedOcrLedOcr.AndroidAndroidOcrProcessor.cs:56
n at LedOcr.ViewModels.MainPageViewModel.paddleAction (System.Object
obj) [0x000eb] in
C:userProjectsTempLedOcrLedOcrLedOcrViewModelsMainPageViewModel.cs:102
“
I am testing it with a real device (Android 13)
I copied to tessdata folder under Assets folder and set ‘copy if newer’ for the eng.traineddata
here is my code
public class AndroidOcrProcessor : IOcrProcessor
{
public async Task<string> PerformOcr(string imagePath)
{
if (string.IsNullOrEmpty(imagePath))
{
throw new ArgumentNullException(nameof(imagePath), "Image path cannot be null or empty.");
}
string tessdataPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "tessdata");
string trainedDataPath = Path.Combine(tessdataPath, "eng.traineddata");
if (!Directory.Exists(tessdataPath))
{
Directory.CreateDirectory(tessdataPath);
}
if (!File.Exists(trainedDataPath))
{
using (var assets = Android.App.Application.Context.Assets.Open("tessdata/eng.traineddata"))
using (var dest = File.Create(trainedDataPath))
{
await assets.CopyToAsync(dest);
}
}
if (!Directory.Exists(tessdataPath) || !File.Exists(trainedDataPath))
{
throw new Exception($"Required data not found in {tessdataPath}. Ensure that the 'tessdata' folder contains 'eng.traineddata'.");
}
using (var engine = new TesseractEngine(tessdataPath, "eng", EngineMode.Default))
{
using (var img = Pix.LoadFromFile(imagePath))
{
using (var page = engine.Process(img))
{
string text = page.GetText();
return text;
}
}
}
}
}
This exception occurs in this line
var engine = new TesseractEngine(tessdataPath, "eng", EngineMode.Default);
It means, the tessdataPath exists but somehow TesseractEngine cannot find. Maybe do I need to install another library?
I am using this library https://github.com/charlesw/tesseract/
I used also this Android.App.Application.Context.FilesDir.AbsolutePath; which points the same path of FileSystem.AppDataDirectory. The path is “/data/user/0/com.companyname.ledocr/files”
What is the problem here?