khjde1207 / tesseract_ocr

Tesseract OCR for flutter
BSD 3-Clause "New" or "Revised" License
62 stars 31 forks source link

Web: No Such Method Exception #12

Closed DivisionBell closed 2 years ago

DivisionBell commented 2 years ago

When I start my app locally with Intelli everything is fine. But when I build the app for web and deploy it on my server I get a "no such method" exception. I am usng the basic example from pub.dev String text = await FlutterTesseractOcr.extractText('/assets/images/ocrtest.png', language: 'eng', args: { "psm": "4", "preserve_interword_spaces": "1", });

Any idea how to fix this?

Thanks a lot for this awesome package! It works great when executed locally!

khjde1207 commented 2 years ago

difficult. There seems to be an error in this part. I don't know how to solve it.... https://github.com/khjde1207/tesseract_ocr/blob/668a1a7dcb42a444c9578309d3768fa7b781693b/lib/web.dart#L22

If you build with the --dart-define=Dart2jsOptimization=O0 option, you can see an error

flutter build web --profile --dart-define=Dart2jsOptimization=O0
khjde1207 commented 2 years ago

I tried changing the logic, but another error appears.

var object = context['Tesseract'];
    var obj = object.callMethod('createWorker');
    await obj.callMethod('load');
    await obj.callMethod('loadLanguage', [language]);
    await obj.callMethod('initialize', [language]);

createWorker.js:173 Uncaught Error: TypeError: Cannot read property 'TessBaseAPI' of undefined

khjde1207 commented 2 years ago

It's really hard. I don't know if I can fix it. I'll find a way. It's going to take a long time. Sorry

khjde1207 commented 2 years ago

I can't find a way The ocr operation was modified to be done in javascript.

./web/index.html

<body>
  <script src='https://unpkg.com/tesseract.js@2.1.0/dist/tesseract.min.js'></script>
  <script>
    async function _extractText(imagePath , mapData){
      var worker = Tesseract.createWorker();
      await worker.load();
      await worker.loadLanguage(mapData.language)
      await worker.initialize(mapData.language)
      await worker.setParameters(mapData.args)
      var rtn = await worker.recognize(imagePath, {}, worker.id);
      await worker.terminate();
      if(mapData.args["tessjs_create_hocr"]){
        return rtn.data.hocr;  
      }
      return rtn.data.text;
    }
  </script>
  ...
  ..
  .
</body>
DivisionBell commented 2 years ago

I found a workaround which may be useful for others or help you fixing the issue.

I call the Tesseract function "recognize" directly, not using the worker at all.

@JS("Tesseract")
library tesseract;
import 'package:node_interop/util.dart';
// ....
external dynamic recognize(image, langs, options);

class Ocr {
  Future<String> _extractText(File file) async {
    var result = await promiseToFuture(recognize(file, 'eng', jsify({
      "psm": "4",
      "preserve_interword_spaces": "1",
    })));
    // "dartify" is from the package "node_interop". You can find it on pub.dev.
    return (dartify(result ) as Map<dynamic, dynamic>)['data']['text'];
  }
}

The following code works locally, but does NOT when deployed ! I tried to use it to return result as a string. return result ?.data?.text;

khjde1207 commented 2 years ago

thanks. Tesseract.recognize function does not support Paramters. tessedit_ocr_engine_mode tessedit_pageseg_mode tessedit_char_whitelist preserve_interword_spaces user_defined_dpi tessjs_create_hocr tessjs_create_tsv tessjs_create_box tessjs_create_unlv tessjs_create_osd