Web TippsUse custom web fonts in Google Sheets charts(08.09.2026 um 17:05 Uhr)
Web TippsIntroducing the new 1Password App for Google Chat(08.09.2026 um 18:02 Uhr)
Web TippsUse custom web fonts in Google Sheets charts(08.09.2026 um 17:05 Uhr)
Web TippsIntroducing the new 1Password App for Google Chat(08.09.2026 um 18:02 Uhr)

🔧 Programmierung 🕛 vor 1 Jahr 8 Min Lesezeit
0

Building a Flutter VIN Scanner for Windows Using Dynamsoft Capture Vision C++ SDK

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

The VIN (Vehicle Identification Number) is a unique 17-character code assigned to every motor vehicle. It serves as a fingerprint for the vehicle, providing essential information such as the manufacturer, model, engine type, year of production, and country of origin. In this tutorial, we will demonstrate how to perform VIN recognition on Windows using Flutter and the Dynamsoft Capture Vision C++ SDK.






Flutter Windows VIN Scanner Demo








Prerequisites





  • : Download the tar.gz file and extract it. This source code package for Python includes all necessary header files and libraries for C++.





  • Use the VINScanner.json template from dynamsoft_capture_vision_bundle-2.4.2100/resource/Templates/ as a reference to create a new VIN.json file.


    CODE
    {
    "LabelRecognizerTaskSettingOptions": [
    {
    "Name": "task_vin_text",
    "TextLineSpecificationNameArray": [
    "tls_vin_text"
    ],
    "SectionImageParameterArray": [
    {
    "Section": "ST_REGION_PREDETECTION",
    "ImageParameterName": "ip_recognize_text"
    },
    {
    "Section": "ST_TEXT_LINE_LOCALIZATION",
    "ImageParameterName": "ip_recognize_text"
    },
    {
    "Section": "ST_TEXT_LINE_RECOGNITION",
    "ImageParameterName": "ip_recognize_text"
    }
    ]
    }
    ],
    "TextLineSpecificationOptions": [
    {
    "Name": "tls_vin_text",
    "CharacterModelName": "VIN",
    "StringRegExPattern": "[0-9A-HJ-NPR-Z]{9}[1-9A-HJ-NPR-TV-Y][0-9A-HJ-NPR-Z]{2}[0-9]{5}",
    "CharHeightRange": [
    5,
    1000,
    1
    ],
    "StringLengthRange": [
    17,
    17
    ],
    "OutputResults": 1
    }
    ],
    "CaptureVisionTemplates": [
    {
    "Name": "ReadVINText",
    "ImageROIProcessingNameArray": [
    "roi_vin_text"
    ]
    }
    ],
    "ImageParameterOptions": [
    {
    "Name": "ip_recognize_text",
    "TextDetectionMode": {
    "Mode": "TTDM_LINE",
    "Direction": "HORIZONTAL",
    "CharHeightRange": [
    5,
    1000,
    1
    ],
    "Sensitivity": 7
    },
    "GrayscaleTransformationModes": [
    {
    "Mode": "GTM_ORIGINAL"
    },
    {
    "Mode": "GTM_INVERTED"
    }
    ]
    }
    ],
    "TargetROIDefOptions": [
    {
    "Name": "roi_vin_text",
    "TaskSettingNameArray": [
    "task_vin_text"
    ]
    }
    ],
    "CharacterModelOptions": [
    {
    "Name": "VIN",
    "DirectoryPath": "",
    "CharSet": {
    "ExcludeChars": [
    "O",
    "Q",
    "I"
    ]
    }
    }
    ]
    }



    Note: The parameters in this template are tailored for OCR only. To successfully load the model, the DirectoryPath must be dynamically assigned.




  • Add the model directories to the assets section of the pubspec.yaml file to package the resources with the app.


    CODE
    assets:
    - lib/model/mrz/
    - lib/model/vin/




  • In lib/flutter_ocr_sdk_method_channel.dart, update the loadModel function to load the VIN template file and set the DirectoryPath dynamically.


    CODE
    Future<int?> loadModel({ModelType modelType = ModelType.mrz}) async {
    var directory =
    'data/flutter_assets/packages/flutter_ocr_sdk/lib/model/mrz/';
    String modelPath = 'packages/flutter_ocr_sdk/lib/model/mrz/';
    var fileName = "MRZ";
    var templateName = 'MRZ.json';

    if (modelType == ModelType.vin) {
    fileName = "VIN";
    templateName = 'VIN.json';
    modelPath = 'packages/flutter_ocr_sdk/lib/model/vin/';
    directory =
    './data/flutter_assets/packages/flutter_ocr_sdk/lib/model/vin/';
    }

    ...

    var templatePath = join(modelPath, templateName);
    String template = await loadAssetString(templatePath);

    if (isDesktop) {
    String exePath = Platform.resolvedExecutable;
    String exeDir = dirname(exePath);
    String assetPath = join(exeDir, directory);
    var templateMap = json.decode(template);
    templateMap['CharacterModelOptions'][0]['DirectoryPath'] = assetPath;

    await methodChannel
    .invokeMethod('loadModel', {'template': json.encode(templateMap)});
    }
    }



    Explanation





    • Platform.resolvedExecutable: Fetches the path of the executable file.


    • dirname: Retrieves the directory containing the executable.

    • The absolute path of the model directory is dynamically constructed and assigned to the DirectoryPath field in the JSON template.








  • Implementing VIN Recognition in C++



    When implementing VIN recognition in C++ for a Flutter application, it’s essential to ensure that CPU-intensive tasks are executed on separate threads to prevent blocking the main thread. Dynamsoft Capture Vision SDK simplifies this by providing asynchronous APIs, minimizing the need for manual threading.



    Here are the steps to implement VIN recognition in dlr_manager.h:





    1. Create a MyCapturedResultReceiver class to receive the VIN recognition results and send them back to Dart.


      CODE
      class MyCapturedResultReceiver : public CCapturedResultReceiver
      {
      public:
      vector<CRecognizedTextLinesResult *> results;
      vector<std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>>> pendingResults = {};
      EncodableList out;

      public:
      void OnRecognizedTextLinesReceived(CRecognizedTextLinesResult *pResult) override
      {
      WrapResults(pResult);
      }

      void sendResult()
      {
      std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result = std::move(pendingResults.front());
      pendingResults.erase(pendingResults.begin());
      result->Success(out);
      out.clear();
      }

      void WrapResults(CRecognizedTextLinesResult *pResults)
      {

      if (!pResults)
      {
      return;
      }

      int count = pResults->GetItemsCount();

      for (int i = 0; i < count; i++)
      {
      EncodableList area;

      const CTextLineResultItem *result = pResults->GetItem(i);
      CPoint *points = result->GetLocation().points;

      int x1 = points[0][0];
      int y1 = points[0][1];
      int x2 = points[1][0];
      int y2 = points[1][1];
      int x3 = points[2][0];
      int y3 = points[2][1];
      int x4 = points[3][0];
      int y4 = points[3][1];

      EncodableMap map;
      map[EncodableValue("confidence")] = EncodableValue(result->GetConfidence());
      map[EncodableValue("text")] = EncodableValue(result->GetText());
      map[EncodableValue("x1")] = EncodableValue(x1);
      map[EncodableValue("y1")] = EncodableValue(y1);
      map[EncodableValue("x2")] = EncodableValue(x2);
      map[EncodableValue("y2")] = EncodableValue(y2);
      map[EncodableValue("x3")] = EncodableValue(x3);
      map[EncodableValue("y3")] = EncodableValue(y3);
      map[EncodableValue("x4")] = EncodableValue(x4);
      map[EncodableValue("y4")] = EncodableValue(y4);
      area.push_back(map);

      out.push_back(area);
      }
      }
      };



      Explanation





      • OnRecognizedTextLinesReceived: Callback invoked when recognition results are ready.


      • WrapResults: Converts the results into a Dart-compatible format.


      • sendResult: Sends results back to Dart using the Flutter method channel.




    2. Create a MyImageSourceStateListener class to observe the state of the recognition task:


      CODE
      class MyImageSourceStateListener : public CImageSourceStateListener
      {
      private:
      CCaptureVisionRouter *m_router;
      MyCapturedResultReceiver *m_receiver;

      public:
      MyImageSourceStateListener(CCaptureVisionRouter *router, MyCapturedResultReceiver *receiver)
      {
      m_router = router;
      m_receiver = receiver;
      }

      void OnImageSourceStateReceived(ImageSourceState state)
      {
      if (state == ISS_EXHAUSTED)
      {
      m_router->StopCapturing();
      m_receiver->sendResult();
      }
      }
      };



      Explanation





      • ISS_EXHAUSTED: Indicates the task is completed, and results can be sent back to Dart.




    3. Set the license key, initialize MyCapturedResultReceiver, CImageSourceStateListener, CFileFetcher and CCaptureVisionRouter in the int Init(const char *license) function:


      CODE
      MyCapturedResultReceiver *capturedReceiver;
      CImageSourceStateListener *listener;
      CFileFetcher *fileFetcher;
      CCaptureVisionRouter *cvr;

      int Init(const char *license)
      {
      char errorMsgBuffer[512];
      int ret = CLicenseManager::InitLicense(license, errorMsgBuffer, 512);
      printf("InitLicense: %s\n", errorMsgBuffer);

      cvr = new CCaptureVisionRouter;

      fileFetcher = new CFileFetcher();
      ret = cvr->SetInput(fileFetcher);
      if (ret)
      {
      printf("SetInput error: %d\n", ret);
      }

      capturedReceiver = new MyCapturedResultReceiver;
      ret = cvr->AddResultReceiver(capturedReceiver);
      if (ret)
      {
      printf("AddResultReceiver error: %d\n", ret);
      }

      listener = new MyImageSourceStateListener(cvr, capturedReceiver);
      ret = cvr->AddImageSourceStateListener(listener);
      if (ret)
      {
      printf("AddImageSourceStateListener error: %d\n", ret);
      }

      return ret;
      }



      Explanation





      • CCaptureVisionRouter: Manages the recognition process.


      • CFileFetcher: Loads the image file or buffer.




    4. Add functions to handle VIN recognition from an image file or a camera feed.


      CODE
      void start()
      {
      char errorMsg[512] = {0};
      int errorCode = cvr->StartCapturing("", false, errorMsg, 512);
      if (errorCode != 0)
      {
      printf("StartCapturing: %s\n", errorMsg);
      }
      }

      void RecognizeFile(std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> &pendingResult, const char *filename)
      {
      printf("RecognizeFile: %s\n", filename);
      capturedReceiver->pendingResults.push_back(std::move(pendingResult));
      fileFetcher->SetFile(filename);
      start();
      }

      void RecognizeBuffer(std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> &pendingResult, const unsigned char *buffer, int width, int height, int stride, int format)
      {
      capturedReceiver->pendingResults.push_back(std::move(pendingResult));
      CImageData *imageData = new CImageData(stride * height, buffer, width, height, stride, getPixelFormat(format));
      fileFetcher->SetFile(imageData);
      delete imageData;

      start();
      }



      Explanation





      • StartCapturing: Starts a recognition task.








    Updating Dart Code for MRZ and VIN Recognition



    With the Flutter plugin complete, you can now update the example app to support both MRZ and VIN recognition.





    1. Create a toggle button to switch between MRZ and VIN recognition in example/lib/home_page.dart:


      CODE
      bool isMrzSelected = true;

      FlutterOcrSdk detector = FlutterOcrSdk();
      ModelType model = ModelType.mrz;

      Future<void> switchModel(ModelType newModel) async {
      model = newModel;
      await detector.loadModel(modelType: newModel);
      }

      return Scaffold(
      body: Column(
      children: [
      title,
      description,
      Center(
      child: ToggleButtons(
      borderRadius: BorderRadius.circular(10),
      isSelected: [isMrzSelected, !isMrzSelected],
      selectedColor: Colors.white,
      fillColor: Colors.orange,
      color: Colors.grey,
      children: const [
      Padding(
      padding: EdgeInsets.symmetric(horizontal: 20),
      child: Text('MRZ'),
      ),
      Padding(
      padding: EdgeInsets.symmetric(horizontal: 20),
      child: Text('VIN'),
      ),
      ],
      onPressed: (index) {
      setState(() {
      isMrzSelected = (index == 0);
      if (isMrzSelected) {
      switchModel(ModelType.mrz);
      } else {
      switchModel(ModelType.vin);
      }
      });
      },
      ),
      ),
      ...
      ],
      ),
      );




    2. Build and run the Flutter Windows app:


      CODE
      flutter run -d windows




    3. Press the Image Scan button to recognize VIN from an image file.










    Source Code



    https://github.com/yushulx/flutter_ocr_sdk/tree/DCV/example

    Vollständiger Original-Bericht
    Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
    ↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
3 Quellen
Use custom web fonts in Google Sheets charts
2 Quellen
Introducing the new 1Password App for Google Chat
1 Quelle
Context-aware access controls are available for Gemini Enterprise in the Admin console
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Building a Flutter VIN Scanner for Windows Using Dynamsoft Capture Vision C++ SDK

Thematisch verwandte Begriffe: Building, Flutter, Scanner, Windows · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...