{"id":17039045,"url":"https://github.com/dcnick3/pqrs","last_synced_at":"2025-09-02T19:39:18.593Z","repository":{"id":54493110,"uuid":"337060141","full_name":"DCNick3/pqrs","owner":"DCNick3","description":"Portable QR Scanning library","archived":false,"fork":false,"pushed_at":"2025-03-19T23:19:09.000Z","size":14049,"stargazers_count":15,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-26T08:37:18.707Z","etag":null,"topics":["cpp","js","qr","qr-code","qr-code-reader","qr-scanner"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DCNick3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-02-08T11:54:01.000Z","updated_at":"2025-03-19T23:19:13.000Z","dependencies_parsed_at":"2022-08-13T17:40:40.191Z","dependency_job_id":null,"html_url":"https://github.com/DCNick3/pqrs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DCNick3%2Fpqrs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DCNick3%2Fpqrs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DCNick3%2Fpqrs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DCNick3%2Fpqrs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DCNick3","download_url":"https://codeload.github.com/DCNick3/pqrs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248576490,"owners_count":21127414,"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","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":["cpp","js","qr","qr-code","qr-code-reader","qr-scanner"],"created_at":"2024-10-14T08:58:29.892Z","updated_at":"2025-04-12T13:53:14.860Z","avatar_url":"https://github.com/DCNick3.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Pipeline status](https://img.shields.io/gitlab/pipeline/inno_baam/pqrs/master)](https://gitlab.com/inno_baam/pqrs/pipelines/latest)\n[![Version](https://img.shields.io/npm/v/pqrs-js.svg)](https://npmjs.org/package/pqrs-js)\n[![Downloads/week](https://img.shields.io/npm/dw/pqrs-js.svg)](https://npmjs.org/package/pqrs-js)\n[![License](https://img.shields.io/npm/l/pqrs-js.svg)](https://github.com/DCNick3/pqrs-js/blob/master/package.json)\n\n# pqrs\n\nA Portable QR Scanning library.\nImage processing is very much based on algorithms used in [BoofCV](https://boofcv.org).\nDecoding and error correction is based on [zxing](https://github.com/zxing/zxing) \n\nRequires C++17 compiler. Seems to work with GCC and Clang.\n\nCurrently can be used in C++, Android (via JNI) and Web (via emscripten).\n\n### Demo\n\nDemo is available [here](https://dcnick3.me/js/pqrs-demo/)\n\n### Using in js projects\n\nThere is an [npm package](https://www.npmjs.com/package/pqrs-js)\n\nIt will work out-of-the box in nodejs and will probably require special handling for webassembly file distribution in browser.\n\nYou can see [pqrs-cli](https://github.com/DCNick3/pqrs-cli) for example usage.\n\n### Using in Android projects\n\nThe android library is published on maven central as `me.dcnick3.pqrs:pqrs-android` (see https://central.sonatype.com/artifact/me.dcnick3.pqrs/pqrs-android). Add it to your project.\n\nThen call `PqrsScanner.scanGrayscale` and get the scan results back. The Android API is a bit rough and is only really designed to be used as a Android CameraX analyzer. See example usage [here](https://github.com/DCNick3/baam-android/blob/df8b73c1d98c793701cb0f2a4db053daf17927b9/app/src/main/java/me/dcnick3/baam/ui/camera/ScannerScreen.kt#L82).\n\n## Long and sad story as to why this was created\n\nI needed a QR scanning library in web application. \nSo, I went with [jsQR](https://github.com/cozmo/jsQR), which is one of [zxing](https://github.com/zxing/zxing) ports to js.\nWhat could go wrong? Apparently, a lot.\n\nThe scanner was used to scan an image projected to screen in an intensively lit big lecture room.\nUsers were to scan it without leaving their places. And this actually posed a challenge...\n\nI have distinguished two conditions that pose a challenge to zxing:\n\n### 1. Low Contrast\n\n![](images/locontrast.png)\n\nFirst of them is low projector image contrast, which is an inherent problem of all projectors.\nThey cannot make \"black\" any darker than ambient lighting, so the only way to increase contrast is to make light regions even lighter, which is limited by physical abilities of the light source.\n\nThis affects the first stage of QR code scanning: detection \u0026 localization. Most scanners begin with image binarization and then try to detect finder patterns (the noticable three squares at the angles of the QR code).\n\nLow contrast is quite a challenge for most binarization algorithms and, for no surprise, zxing struggled with it:\n\n![](images/badbin.png)\n\n### 2. High perspective distortions\n\n![](images/perspective.png)\n\nThe second problem was due to the fact that lecture room was quite big and users were to scan QR without leaving their seats.\nThis required scanning from quite extreme angles and zxing does not handle huge perspective distortions caused by this quite well.\n\n### The solution\n\nWith these cases in mind, I collected example images and used them to survey already existing QR scanners to find those reasonably handling my problematic cases.\n\nThat's when I found [BoofCV](https://boofcv.org/), which boasted [surprisingly good performance](https://boofcv.org/index.php?title=Performance:QrCode).\nAnd apparently, it was actually worked pretty good in these conditions. \nThere was only one problem: it's written in Java, which is not straightforward to run in browser context.\n\nSo, I've decided to write a C++ port(-ish) of BoofCV QR scanner and compile it to webassembly using emscripten.\n\nFrom this I got, on one hand, an ability to use it in much more languages than BoofCV (C++, arguably, has interoperability rate comparable to that of C) and performance (wasm is quite close to what you can get in native code).\n\nIt is not a direct port, some corners were cut (where it seemed like it would not affect performance or scanning quality), some features were added (like local thresholding when sampling QR code modules, which handled the uneven lighting).\n\n## Known Issues\n\n- The scanner can't scan QR codes of version 7 \u0026 higher. I haven't yet investigated why\n- The scanner struggles with non-standard novelty QR codes (non-standard colors, low margins, non-standard shapes for finder patterns, etc). This is unlikely to be fixed.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdcnick3%2Fpqrs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdcnick3%2Fpqrs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdcnick3%2Fpqrs/lists"}