{"id":33125738,"url":"https://github.com/mdelete/node-tesseract-native","last_synced_at":"2025-11-20T00:02:04.400Z","repository":{"id":5855358,"uuid":"7072139","full_name":"mdelete/node-tesseract-native","owner":"mdelete","description":"C++ module for node providing OCR with tesseract and leptonica","archived":false,"fork":false,"pushed_at":"2018-11-17T21:36:10.000Z","size":56,"stargazers_count":52,"open_issues_count":0,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-02T15:14:42.491Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"johnulist/Drafts-Zuha-Cakephp-Plugin","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mdelete.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-12-08T21:05:19.000Z","updated_at":"2025-06-30T12:57:17.000Z","dependencies_parsed_at":"2022-09-16T12:10:57.381Z","dependency_job_id":null,"html_url":"https://github.com/mdelete/node-tesseract-native","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/mdelete/node-tesseract-native","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdelete%2Fnode-tesseract-native","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdelete%2Fnode-tesseract-native/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdelete%2Fnode-tesseract-native/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdelete%2Fnode-tesseract-native/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mdelete","download_url":"https://codeload.github.com/mdelete/node-tesseract-native/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdelete%2Fnode-tesseract-native/sbom","scorecard":{"id":632976,"data":{"date":"2025-08-11","repo":{"name":"github.com/mdelete/node-tesseract-native","commit":"cc6e82fba322044eb8cda079da84077b5affcd25"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.6,"checks":[{"name":"Code-Review","score":0,"reason":"Found 2/29 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 3 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-21T08:24:30.114Z","repository_id":5855358,"created_at":"2025-08-21T08:24:30.114Z","updated_at":"2025-08-21T08:24:30.114Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":285348528,"owners_count":27156475,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-19T02:00:05.673Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-11-15T06:00:52.704Z","updated_at":"2025-11-20T00:02:04.394Z","avatar_url":"https://github.com/mdelete.png","language":"C++","funding_links":[],"categories":["Software"],"sub_categories":["OCR libraries by programming language"],"readme":"node-tesseract-native\n=====================\n\nC++ module for node providing OCR with tesseract and leptonica\n\nPrerequisites\n-------------\n * Have linux or OSX (at least these are tested OSes)\n * Have node and node-gyp installed\n * Have leptonica (~1.68) libs and headers installed\n * Have tesseract (~3.02) libs and headers installed\n\nBuild\n-----\nCheckout the repository and build it yourself using (you will also need this for the *node10* branch)\n\n    node-gyp configure \u0026\u0026 node-gyp build\n\nor use npm\n\n    npm install tesseract_native for nodejs \u003e 0.12.0 \u003c= 8.x.y \n\nor\n\n    npm install tesseract_native@0.4.1 for nodejs \u003e= 0.9.4 \u003c 0.12.0\n\nSupported Picture Formats\n-------------------------\n\nThe module can handle every picture format leptonica can handle (see there), but as this module is likely to be used in an online service, pictures should be as small as possible. A 1.3 Megapixel picture converted to B/W using adaptive threshold filtering, saved as PNG will be 50KB on average. This is were you want to go.\n\nTest your setup\n---------------\n\nYou can test your setup using the provided *test.js* script on the command-line\n\n    $ node test.js HelloWorld.jpg\n\nExample server\n--------------\n\nThe code below shows a fully functional server where you can POST pictures to. The response will contain the recognized plain text or be empty if nothing was recognized or something went wrong.\n\n    var tesseract = require('tesseract_native');\n    var http = require('http');\n    \n    var server = http.createServer(function(request, response)\n    {\n        if(request.method === 'POST')\n        {\n            var totalSize = 0;\n            var bufferList = new Array();\n            var myOcr = new tesseract.OcrEio();\n            \n            request.on('data', function(data) {\n                bufferList.push(data);\n                totalSize += data.length;\n                if (totalSize \u003e 1e6) {\n                    console.log('Request body too large');\n                    request.connection.destroy();\n                }\n            });\n            \n            request.on('end', function() {\n                var buffer = Buffer.concat(bufferList, totalSize);\n                myOcr.ocr(buffer, function(err, result) {\n                    if(err) {\n                        response.writeHead(500, {'Content-Type': 'text/plain'});\n                        response.end(\"Error \" + err);\n                    } else {\n                        response.writeHead(200, {'Content-Type': 'text/plain'});\n                        response.end(result);\n                    }\n                });\n            });\n            \n        } else {\n            request.connection.destroy();\n        }\n    }).listen(process.argv[2]);\n    \nParameters\n----------\n    \nThe OCR function also accepts a config object as second and the callback as third parameter like this:\n\n    myOcr.ocr(buffer, { lang:\"eng\", rect:[0,0,400,400] }, function(result) {\n        // do something\n    });\n    \nThe first supported parameter is `tessdata`, which is the path to you Tesseract data directory (`/usr/local/share/tessdata/` by default). The second is `lang` which can be any three-character code for a language you have installed with Tesseract (`eng` by default). The third is `rect`, which is an array describing a rect of the form [`X`, `Y`, `WIDTH`, `HEIGHT`] limiting the image region for recognition. If you try the above rect with the provided test image it should land you in *hell*...\nAnother parameter `psm` which takes an Integer from `0` to `10` configuring the page segmentation mode as in the table below. The default mode is `3`.\n\nValue | Meaning\n------|-----\n0     | Orientation and script detection (OSD) only.\n1     | Automatic page segmentation with OSD.\n2     | Automatic page segmentation, but no OSD, or OCR.\n3     | Fully automatic page segmentation, but no OSD. (Default)\n4     | Assume a single column of text of variable sizes.\n5     | Assume a single uniform block of vertically aligned text.\n6     | Assume a single uniform block of text.\n7     | Treat the image as a single text line.\n8     | Treat the image as a single word.\n9     | Treat the image as a single word in a circle.\n10    | Treat the image as a single character.\n\n\nWhy?\n----\n\nThe question may arise. I've seen many tesseract wrappers for node and none of them I found did it quite right, some of them even did it wrong. The philosophy (and necessity) behind node is not to block, so everything that does work has to do it asynchronously and emit an event/execute a closure when it's done. If you don't do that, your node application will simply not perform well.\n\nBut even in this code you can see a very crude solution, performance-wise. The tesseract api is instantiated and initialized on every call to the *ocr* method. Why did't I do that when loading the module or when the constructor gets called? It has multiple reasons:\n\n * Simplicity: Initializing tesseract involves file system access, that means, must be performed asynchronously. The OCR work is done by adding the function to the asynchronous *uv_queue_work*, for simplicity I bundled all time-consuming tasks in the function that gets passed to the queue. So even though initializing wastes some cycles, it is still perfectly non-blocking.\n\n * Flexiblity: The language setting is passed on initialization, so by initializing on each request, the language used for detection can be set with each request.\n\n * Robustness: The tesseract context may not be thread-safe. There are hints in the tesseract code that suggest that. I will look further into it and I will be experimenting with a version that initializes the tesseract context at load time.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmdelete%2Fnode-tesseract-native","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmdelete%2Fnode-tesseract-native","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmdelete%2Fnode-tesseract-native/lists"}