Coder Social home page Coder Social logo

maslick / koder Goto Github PK

View Code? Open in Web Editor NEW
226.0 11.0 24.0 3.81 MB

QR/bar code scanner for the Browser

Home Page: https://koder-prod.web.app

License: MIT License

HTML 10.93% JavaScript 70.84% CSS 4.04% Makefile 1.51% C++ 9.45% Dockerfile 3.22%
qrcode qr react wasm emscripten barcode upca upce ean8 ean13

koder's Introduction

🚀 NEW: Check Out Kameroon - QR/Bar Code Scanner as a Service 🚀

=koder=

QR/bar code scanner for the Browser

npm Build Status License: MIT

💡 Demo

https://koder-prod.web.app

🚀 Features

  • QR/barcode module implemented in WebAssembly
  • Barcode support (ISBN, UPC-A, UPC-E, EAN-8, EAN-13, I25, ITF-14, CODE-128, CODE-39, CODE-93, CODABAR, DATABAR)
  • Uses Zbar C++ library (version 0.23.90)
  • Packaged as PWA (caching files with Service Worker, Add to Home Screen)
  • Mobile first (can be used on a Laptop as well)
  • Multiplatform (iOS, Android, Desktop)
  • QR/bar code recognition logic is performed off the browser's Main thread (i.e. Web Worker)
  • koder React component supports a jsqr based Web Worker (see jsQrWorker.js)
  • Emscripten-zbar-sdk Docker image based on emscripten/emsdk, Dockerfile
  • ReactJS component
  • Vanilla JS example
  • 🆕 Turn on/off the beep sound
  • 🆕 Support for UPN QR (Slovenia only)
  • 🆕 EU Digital Covid Certificate validator (vaccination, test), works in offline mode!
  • 🆕 Emscripten v3.1.1
  • 🆕 npm package

⚡ Usage

Install dependencies

npm install --global yarn
yarn install --frozen-lockfile

Run React app

npm run start
open https://locahost:8080

Productionize

npm run build                # -> build React app into ./public
npm run prod                 # -> serve static web app on port 8082
open http://localhost:8082

⚡ NPM module

npm install @maslick/koder
// CommonJS
const Koder = require('@maslick/koder');

// ES6 modules
import Koder from '@maslick/koder';
const Koder = require('@maslick/koder');
const {loadImage, createCanvas} = require("canvas");

const getImageData = async (src) => {
  const img = await loadImage(src);
  const canvas = createCanvas(img.width, img.height);
  const ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0);
  return {
    data: ctx.getImageData(0, 0, img.width, img.height).data,
    width: img.width,
    height: img.height
  };
};

(async () => {
  const url = 'https://raw.githubusercontent.com/maslick/koder/master/screenshots/app_1.png';
  const koder = await new Koder().initialized;
  const {data, width, height} = await getImageData(url);

  const t0 = new Date().getTime();
  const res = koder.decode(data, width, height);
  const t1 = new Date().getTime();

  console.log(`Scanned in ${t1-t0} ms`);  // Scanned in 7 ms
  console.log(res);                       // http://en.m.wikipedia.org
})();

♠️ Development

Fetch or build the Builder image

docker pull maslick/emscripten-zbar-sdk
docker build -t maslick/emscripten-zbar-sdk -f docker/Dockerfile docker

Build WASM artifacts

# Linux, Mac Intel
docker run \
  -e INPUT_FILE=zbar/qr.cpp \
  -e OUTPUT_FILE=zbar \
  -e OUTPUT_DIR=public/wasm \
  -v $(pwd):/app \
  maslick/emscripten-zbar-sdk make -B
  
# Mac M1/M2
docker run \
  --platform linux/amd64 \
  -e INPUT_FILE=zbar/qr.cpp \
  -e OUTPUT_FILE=zbar \
  -e OUTPUT_DIR=public/wasm \
  -v $(pwd):/app \
  maslick/emscripten-zbar-sdk make -B

Clean the build artifacts (if necessary):

OUTPUT_DIR=public/wasm OUTPUT_FILE=zbar make clean

🔭 References

koder's People

Contributors

dependabot[bot] avatar maslick avatar zigastegu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

koder's Issues

Request for Code 128 support

The underlying Zbar lib supports GS1 128 / Code 128. Would be great to have that support here as well as it's a commonly used barcode.

Screenshot 2021-09-13 at 20 10 17

Halftone QR support

Confirm by changing [ ] to [x] below to ensure that it's a bug:

I was evaluation this package and this looks good, thanks for creating this!

But, as I dived to custom QR code generation, I found somewhat cool project: https://github.com/fangj/Halftone-QRCode-Generator
More about this on https://backdrifting.net/post/016_halftone_qr

Anyways, for some reason I could not get any of those codes correctly read by using https://koder-prod.web.app

This is totally not priority case, but I am more interested about finding out why those actually don't work.

I am using Pixel 7 here, if that is somehow relevant.

Beep doesn't work after turning off screen

Confirm by changing [ ] to [x] below to ensure that it's a bug:

Describe the bug
When I turn off the screen on my mobile phone, and then turn it back on, the beep sound doesn't work anymore, even if the beep setting is ON.

To Reproduce (observed behavior)

  • Visit https://qr.maslick.tech on your mobile phone
  • Make sure to enable beep
  • Scan a code (beep works)
  • Turn off screen
  • Turn on screen
  • Scan the code again (beep doesn't work anymore)

Expected behavior
Beep feature should work regardless at all times

Logs/output
n/a

Screenshots
n/a

Please complete the following information:

  • Device: iPhone 11
  • OS: iOS 15.2.1
  • Browser Safari

Additional context
n/a

Angular example to reference

Is your feature request related to a problem? Please describe.
Currently you have a plain JS and a React version. Missing is an Angular component that can be easily integrated.

Describe the solution you'd like
It would be incredible to have an Angular example to look at. It would still be based off the NPM package, but the usage thereof would be wrapped in an Angular demo.

Describe alternatives you've considered
Sure, it's possible to look through either the React or vanilla code and create a component, but it would be quite time consuming, especially for people who are not as familiar with doing things that way. Service workers also become quite complicated.

Support for decoding binary-encoded QRs?

Is your feature request related to a problem? Please describe.
Yes - As far as I can tell, when scanning a binary-encoded QR code, it's converted into a string, and the bytes do not match up when I attempt to decode it.

Describe the solution you'd like
In an ideal world, it'd be great if Koder could automatically detect when a qr code is binary-encoded, and automatically return a byte array / UInt8Array. But another nice option would be if Koder simply always outputted a byte array, because you can always use a TextDecoder to convert it to a string later in the pipeline.

Describe alternatives you've considered

  1. I tried using TextEncoder to encode the returned string back into a Uint8Array, but the bytes were completely different. Putting an example at the bottom of the issue.
  2. I've tried delving into the code and modifying getScanResults() to return an array of uint8_t* instead of str* without using strcpy, and then modifying koder.js to copy the pointer as a JS Array / UInt8Array, but I got stuck on the last part. I couldn't find any methods related to copying an array pointer back to JS in Emscripten's preamble, but I found this stackoverflow post and it went WAY over my head. I've never done anything with WebAssembly and my experience with C++ is extremely limited, so this is a little above my pay grade, so to speak.

Additional context
I'm writing a mobile web app that's designed to use QR codes to transmit data between devices. Since the QR codes are being both created and scanned in-app, we have the benefit of the scanner "expecting" the qr code to be encoded in a specific format.
I'm using the NodeJS package qrcode to encode my qr codes. When compressing my data, I'm using LZMA, which already outputs an array of bytes. When I have to encode that array of bytes to Base64, it costs an additional 33% of data size, so it'd be ideal if I could just encode it in binary and then decode it as binary. According to the readme of qrcode (https://www.npmjs.com/package/qrcode#binary-data), converting binary data to a JS string adds extra bytes, which I assume is the reason why the bits in the outputted string look completely different from the original data.

Example of using TextEncoder to try and recover the original bytes:
Original Uint8Array:

221, 128, 128, 128, 130, 48, 131, 128, 128, 128, 128, 128, 128, 128, 189, 8, 7, 98, 161, 94, 30, 168, 143, 80, 172, 15, 239, 93, 198, 149, 251, 171, 84, 103, 81, 243, 211, 208, 147, 195, 233, 145, 36, 205, 135, 118, 48, 202, 120, 129, 152, 65, 109, 218, 36, 249, 121, 153, 165, 158, 18, 205, 209, 250, 171, 153, 126, 126, 83, 118, 236, 74, 185, 112, 171, 179, 196, 92, 170, 222, 104, 147, 56, 229, 229, 42, 55, 210, 235, 47, 151, 238, 63, 206, 178, 21, 4, 89, 213, 170, 164, 99, 27, 114, 136, 208, 30, 71, 208, 248, 159, 171, 55, 53, 238, 72, 195, 1, 175, 140, 205, 94, 106, 75, 189, 130, 20, 254, 159, 50, 35, 236, 12, 60, 92, 226, 164, 249, 28, 72, 42, 3, 95, 249, 77, 139, 204, 23, 231, 208, 103, 244, 140, 80, 240, 197, 199, 17, 201, 79, 32, 167, 27, 0, 194, 98, 104, 217, 243, 161, 103, 97, 240, 90, 190, 191, 48, 137, 241, 197, 140, 114, 201, 210, 120, 199, 71, 116, 234, 27, 86, 154, 186, 146, 217, 196, 232, 254, 150, 40, 3, 244, 60, 126, 141, 180, 44, 4, 33, 82, 211, 220, 237, 69, 247, 22, 45, 25, 221, 242, 232, 210, 195, 130, 249, 0, 87, 101, 93, 57, 89, 162, 19, 238, 202, 144, 176, 165, 29, 68, 51, 137, 236, 206, 30, 82, 206, 194, 11, 86, 151, 50, 82, 91, 186, 8, 107, 186, 60, 241, 8, 207, 152, 133, 18, 55, 231, 95, 213, 158, 136, 45, 173, 252, 48, 40, 130, 64, 103, 78, 88, 81, 77, 180, 68, 86, 6, 111, 151, 192, 212, 95, 55, 179, 224, 223, 25, 224, 68, 166, 8, 105, 212, 143, 37, 145, 171, 176, 209, 128, 223, 160, 201, 121, 138, 242, 66, 118, 162, 50, 232, 182, 172, 181, 8, 209, 217, 154, 229, 183, 186, 52, 65, 101, 45, 42, 111, 175, 8, 145, 253, 26, 108, 88, 133, 29, 47, 194, 64, 75, 156, 220, 46, 14, 40, 246, 159, 109, 97, 217, 166, 40, 31, 187, 40, 103, 157, 134, 68, 238, 237, 140, 106, 68, 96, 250, 140, 83, 194, 2, 98, 102, 62, 153, 32, 178, 241, 12, 224, 172, 25, 94, 241, 23, 173, 178, 40, 135, 66, 42, 212, 214, 19, 255, 143, 159, 255, 192, 86, 24, 5, 248, 59, 217, 163, 94, 146, 173, 17, 144, 27, 190, 47, 105, 187, 132, 141, 148, 155, 208, 169, 20, 172, 37, 96, 151, 17, 227, 214, 233, 138, 98, 136, 112, 156, 167, 204, 167, 197, 62, 173, 189, 97, 203, 71, 227, 70, 13, 93, 161, 172, 231, 123, 113, 77, 62, 37, 119, 50, 79, 11, 150, 208, 218, 19, 223, 125, 126, 182, 98

Resulting string:

'Ý\x80\x80\x80\x820\x83\x80\x80\x80\x80\x80\x80\x80½\b\x07b¡^\x1E¨\x8FP¬\x0Fï]Æ\x95û«TgQóÓÐ\x93Ãé\x91$Í\x87v0Êx\x81\x98AmÚ$ùy\x99¥\x9E\x12ÍÑú«\x99~~SvìJ¹p«³Ä\\ªÞh\x938åå*7Òë/\x97î?β\x15\x04YÕª¤c\x1Br\x88Ð\x1EGÐø\x9F«75îHÃ\x01¯\x8CÍ^jK½\x82\x14þ\x9F2#ì\f<\\â¤ù\x1CH*\x03_ùM\x8BÌ\x17çÐgô\x8CPðÅÇ\x11ÉO §\x1B'

Result of new TextEncoder().encode(str):

195, 157, 194, 128, 194, 128, 194, 128, 194, 130, 48, 194, 131, 194, 128, 194, 128, 194, 128, 194, 128, 194, 128, 194, 128, 194, 128, 194, 189, 8, 7, 98, 194, 161, 94, 30, 194, 168, 194, 143, 80, 194, 172, 15, 195, 175, 93, 195, 134, 194, 149, 195, 187, 194, 171, 84, 103, 81, 195, 179, 195, 147, 195, 144, 194, 147, 195, 131, 195, 169, 194, 145, 36, 195, 141, 194, 135, 118, 48, 195, 138, 120, 194, 129, 194, 152, 65, 109, 195, 154, 36, 195, 185, 121, 194, 153, 194, 165, 194, 158, 18, 195, 141, 195, 145, 195, 186, 194, 171, 194, 153, 126, 126, 83, 118, 195, 172, 74, 194, 185, 112, 194, 171, 194, 179, 195, 132, 92, 194, 170, 195, 158, 104, 194, 147, 56, 195, 165, 195, 165, 42, 55, 195, 146, 195, 171, 47, 194, 151, 195, 174, 63, 195, 142, 194, 178, 21, 4, 89, 195, 149, 194, 170, 194, 164, 99, 27, 114, 194, 136, 195, 144, 30, 71, 195, 144, 195, 184, 194, 159, 194, 171, 55, 53, 195, 174, 72, 195, 131, 1, 194, 175, 194, 140, 195, 141, 94, 106, 75, 194, 189, 194, 130, 20, 195, 190, 194, 159, 50, 35, 195, 172, 12, 60, 92, 195, 162, 194, 164, 195, 185, 28, 72, 42, 3, 95, 195, 185, 77, 194, 139, 195, 140, 23, 195, 167, 195, 144, 103, 195, 180, 194, 140, 80, 195, 176, 195, 133, 195, 135, 17, 195, 137, 79, 32, 194, 167, 27

I can't find any patterns in this result that indicate any resemblance to the original data. Additionally, the array is shorter and I don't know why that would be.

Barcode scanner doesn't work with Iphone 13 Pro

I tried the barcode scanner with Iphone 13 pro using Safari, Chrome and Firefox and it didn't work. The camera doesn't focus and the image gets blurry when trying to read a barcode.

Steps to reproduce the behaviour using the demo page.

1- Open browser and go to https://qr.maslick.tech/
2- Start barcode scanner
3- Aim camera at book's barcode.

Expected behavior

Scanned barcode text.

Device: [Iphone 13 Pro]
OS: [ iOS 15.0]
Browser [Safari, Chrome and Firefox]

Webpack Upgrade - Angular 14

Confirm by changing [ ] to [x] below to ensure that it's a bug:

Describe the bug
Using in angular 14 fails to compile due to newer Webpack version.

To Reproduce (observed behavior)
install & import koder into angular 14 project

Logs/output

./node_modules/@maslick/koder/zbar.js:34:20-43 - Error: Module not found: Error: Can't resolve 'path' in '[project]/node_modules/@maslick/koder'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
        - add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
        - install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback: { "path": false }

./node_modules/@maslick/koder/zbar.js:35:17-30 - Error: Module not found: Error: Can't resolve 'fs' in '[project]/node_modules/@maslick/koder'

Not able to indian AADHAAR card

I was trying this QR code reader on mobile. It was unable to read the QR code on Indian AADHAAR cards. Please let me know on how to deal with it.
aadhaar_image (1)

Help with a React quickstart

Your library looks incredible, Mr Maslov! Sorry for looking like a complete moron but I never worked before with wasm and I am a bit too lost trying to implement anything, just make it work with a simple create-react-app type of base. I tried to organize the React component but it looks way too much to try to adapt into a small, working, piece of component.

Would you have any small snippet on how to simply make it work with a React app? Thank you so much!

Support more barcode formats

Is your feature request related to a problem? Please describe.
Zbar supports more barcodes like CODE39 and others.

Describe the solution you'd like
Make it possible to enable those at run time.

Publish WASM on NPM

Is your feature request related to a problem? Please describe.
Right now WASM file is not distributed in any way...

Describe the solution you'd like
Publish WASM and js file to NPM

Improving the readability for poor devices

Hey mate,

first of all, nice work you have done here! I've tested a few times and it does works smoothly!

The thing is, when using some cheap Android devices that have bad cameras the scanner can't read the barcode.

Would that be a case to improve the original ZBar library or is there something we can do within koder?

Cheers

Fix typos

Confirm by changing [ ] to [x] below to ensure that it's a bug:

Describe the bug
Fix typos in issue-template

To Reproduce (observed behavior)
N/A

Expected behavior
N/A

Logs/output
N/A

Screenshots
N/A

Additional context
N/A

ALL THE WAY UP PARTNER 💪

First thing this is an amazing work...
You saved me allot of time thanx lots.
But I have questions
-How can I enable all barcode types detection supported by ZBAR ?
-When scanning EAN-13 barcodes that starts with zero, it removes the leading zero and consider it as a UPC-A barcode. How to solve this ?

MUCH LOVE...

Koder Failed to initialize

Describe the bug
I received this error when i am trying to initialize the Koder

Aborted(CompileError: wasm validation error: at offset 4: failed to match magic number). Build with -s ASSERTIONS=1 for more info.

To Reproduce (observed behavior)

_import Koder from "@maslick/koder";
useEffect(() => {
  (async () => {
	  try {
		  const setThis = await new Koder().initialized;
		  console.log(setThis);
	  } catch (error) {
		  console.log("Koder Error");
		  console.log(error);
		  alert(error.message);
	  }
  })();
}, []);

Expected behavior
Koder is unable to initialize and throw this error
Aborted(CompileError: wasm validation error: at offset 4: failed to match magic number). Build with -s ASSERTIONS=1 for more info.

Please complete the following information:
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1"

Improve README.md

Is your feature request related to a problem? Please describe.
Let's improve project documentation

Describe the solution you'd like
README.md should be improved targeting possible contributors, so they can easily prepare their development environment

Describe alternatives you've considered
n/a

Additional context
n/a

Barcode scanner doesn't work with Galaxy S10/ Galaxy A52s in Google Chrome

Confirm by changing [ ] to [x] below to ensure that it's a bug:

I tried to use the scanner in my Samsung Galaxy 10 and I couldn't make it work. I tested it on Google Chrome, the camera does not get to focus and the image gets blurry though I tried it out with Firefox and it worked fine with the same phone.

I have tested the scanner also on Samsung galaxy A52s and I had the same results with Google Chrome.

Steps to reproduce the behaviour using the demo page.

1- Open Chrome and go to https://qr.maslick.tech/
2- Start scanner
3- Aim camera at book's barcode.

Expected behavior

Scanned barcode text.

  • Device: [Galaxy S10][Galaxy A52s]
  • OS: [Android 12]
  • Browser [Chrome]
  • Version [98]

Declaration file missing

Confirm by changing [ ] to [x] below to ensure that it's a bug:

Describe the bug
In an Angular 13 project, try to import the Koder npm package.
image

To Reproduce (observed behavior)
Create a new Angular project (Angular 13).
npm install @maslick/koder
Try import the package into a component.

Expected behavior
Should be able to get types in Typescript in an Angular project.

Please complete the following information:

  • Device: [e.g. iPhone6, Desktop]
  • OS: Windows
  • Browser: Chrome
  • Version: 1.8.0

Merge QR and barcode WASMs

So far we've had separate WASM files for QR and bar codes. Since they do not differ in size (390 KB for the wasm + 84 KB for the helper js), it's reasonable to merge these 2 as in the vanilla js example. As a result, the bundle will be slimmer by 474 KB (roughly 50% less)

Add Copy to Clipboard button

Is your feature request related to a problem? Please describe.
Ability to copy the decoded code into Clipboard

Describe the solution you'd like
n/a

Describe alternatives you've considered
n/a

Additional context
n/a

Javascript implementation in Laravel

hello, I'm having problems when I want to display the results after running the qr code using javascript. I tried using test.html but it doesn't show any result. can you help me? I use Laravel base.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.