cozmo / jsQR

A pure javascript QR code reading library. This library takes in raw images and will locate, extract and parse any QR code found within.
https://cozmo.github.io/jsQR/
Apache License 2.0
3.67k stars 606 forks source link

Base64 decoding #96

Open ivanjx opened 5 years ago

ivanjx commented 5 years ago

Is base64 string data type supported with this library?

Thanks

cozmo commented 5 years ago

@realivanjx could you expand on what you mean by this? There's not (as far as I know) a base64 encoding scheme built into QR codes (https://en.wikipedia.org/wiki/QR_code#Encoding). You can of course store binary data directly, or store base64 encoded strings as text.

If you have a QR code with a base64 encoded string as the content, jsQR will just return the encoded string (since there's no indication that it's base64), but you can of course decode it as you normally would decode a base64 string (atob on the client, using Buffer in node JS).

If I'm misunderstanding the question, or if there is example you can show around what you mean I'd love to understand. Thanks!

Ruffio commented 5 years ago

@realivanjx anything?

ivanjx commented 5 years ago

Sorry for the super late response. I have been busy lately. What i mean is if i have an image stored as base64 string can i use this lib to read it and get its qr code string? Hope that makes sense. Thanks...

kpfecteau commented 5 years ago

+1 was looking to use this on a base64 image as well

JaviRpo commented 5 years ago

I'm looking for this too.

I have this image: image

And this is the representative value Base64: data:image/png;base64,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

It would be great if we can decode the qrcode without render the image in an img object.

ansarikhurshid786 commented 5 years ago

I am looking for the same. is this library support base64 string of image.

JaviRpo commented 5 years ago

This is the nearest code that I have to solve my problem (rendering the image)

  public jsQR_fromBase64(base64: string): Promise<QRCode> {
    return new Promise<QRCode>((resolve, reject) => {
      const image: HTMLImageElement = document.createElement('img');
      image.onload = () => {
        const canvas: HTMLCanvasElement = document.createElement('canvas');
        const context: CanvasRenderingContext2D = canvas.getContext('2d');

        canvas.width = image.width;
        canvas.height = image.height;
        context.drawImage(image, 0, 0);

        try {
          const imageData: ImageData = context.getImageData(0, 0, image.width, image.height);

          const qrCode: QRCode = jsQR(imageData.data, imageData.width, imageData.height);
          resolve(qrCode);
        } catch (e) {
          reject(e);
        }
      };
      image.src = base64;
    });
  }

@cozmo Can we include this one or similar into the library?

lebed2045 commented 5 years ago

I'm also very interesting. This is exactly what did I do, using canvas.getContext('2d'), but it sounds suboptimal create new canvas just to render picture and read it again into Uint8ClampedArray format. Is there a way to read picture on frontend directly into format which jsQR can accept the image? Perhaps way to convert HTMLImageElement to Uint8ClampedArray?

zharchimage commented 4 years ago

this solution doesn't work in web-workers

adamreisnz commented 2 years ago

Since this library doesn't seem to be maintained anymore, you can get base64 data url support (and more) out of the box with this one instead: https://github.com/nimiq/qr-scanner (Note: I am not the author)

zanechua commented 2 years ago

You can also do the following for a full server side implementation:

import { getSync as getImageDataFromBuffer } from '@andreekeberg/imagedata';
import jsQR from 'jsqr';

const qrcodeImage= 'base64stringhere';
const qrcodeBuffer = Buffer.from(qrcodeImage, 'base64');
const qrArray = getImageDataFromBuffer(qrcodeBuffer);
const code = jsQR(qrArray.data, qrArray.width, qrArray.height);
cozmo commented 2 years ago

Different definitions of "maintained" I guess - jsQR never has had any desire to in include random image decoding functionality. As @zanechua pointed out there are libraries that do that, and bloating this library is an anti design pattern IMO.

Better to take in image data from any source and let the consumer pass it in as they wish IMO.

adamreisnz commented 2 years ago

With the last publish being 9 months ago, 60 issues open, and little to no response to open issues, I thought it was a fair assessment to make regarding the maintenance status of this package.

Personally I prefer a library that can handle "non-random" image decoding as all I'm interested in is getting the QR code data out of the image. But of course I respect your decision to leave it out of your package.

zanechua commented 2 years ago

I think it's good to have choices. If you prefer an all-in-one package, then perhaps something else may suit you. Otherwise I would just respect the maintainer's wishes on their vision of the package as they've contributed their free time to it. At the end of the day, it's just personal preferences. 😊

That being said, I understand where @adamreisnz is coming from when he uses the metrics to determine if a project is maintained.

However as I've seen in the OSS community, sometimes packages just don't need an update as long as they are working well or have reached full maturity in their intended use case.

I went with this package as I needed something to run in a node backend and not having access to the browser specific js code.

Honestly the library works as intended as @cozmo is following the imageData spec and I think that's a good choice as you have a standard that anyone can refer to.

joseneoito commented 10 months ago

thanks @JaviRpo it worked