【问题标题】:Why I cannot decode QR codes in Javascript?为什么我无法在 Javascript 中解码 QR 码?
【发布时间】:2019-04-02 13:48:05
【问题描述】:

我正在开发 Angular 应用程序并尝试仅在客户端使用 QR 码解码图像并面临下一个错误。

我有下一个流程:

  1. 用户上传图片。
  2. 我从图像中解码二维码。

<input type="file" name="file" id="file" accept="image/*"(change)="qrCodeUploaded($event.target.files)"/>

我已经尝试了下一个库:

  1. https://github.com/zxing-js/library
  qrCodeUploaded(files: FileList): void {
    const fileReader = new FileReader();
    const codeReader = new BrowserQRCodeReader();
    fileReader.readAsDataURL(files[0]);

    fileReader.onload = (e: any) => {
        var image = document.createElement("img");
        image.src = e.target.result;
        setTimeout(() => codeReader.decodeFromImage(image,  e.target.result).then(res => console.log(res)), 100);
    };
  }

适用于某些二维码,但在移动设备上存在问题。如果您将使用手机拍摄 QR 码的照片,则不会对其进行解码。因此,对于移动设备,您需要实现视频。

  1. https://github.com/cozmo/jsQR
  qrCodeUploaded(files: FileList): void {
    const fileReader = new FileReader();
    fileReader.readAsArrayBuffer(files[0]);
    fileReader.onload = (e: any) => {
      console.log(new Uint8ClampedArray(e.target.result));
      console.log(jsQR(new Uint8ClampedArray(e.target.result), 256, 256));
    };
  }

我上传的任何 QR 图像都会出现下一个错误:

core.js:15714 ERROR Error: Malformed data passed to binarizer.
    at Object.binarize (jsQR.js:408)
    at jsQR (jsQR.js:368)

要点链接: https://gist.github.com/er-ant/b5c75c822eb085e70035cf333bb0fb55

请告诉我我做错了什么并提出一些二维码解码的解决方案。打开任何想法:)

【问题讨论】:

  • 这和加密有什么关系?
  • 你读过the readme here?他们期待ImageData(即像素值),您正在给他们一个图像文件的 ArrayBuffer(即二进制内容)。那是行不通的。要从 Blob 中获取 ImageData,您可以执行 createImageBitmap(blob).then(bmp=> { const ctx = Object.assign(document.createElement('canvas'), bmp).getContext('2d'); ctx.drawImage(bmp, 0,0); return ctx.getImageData(0,0,bmp.width,bmp.height); })
  • @Kaiido 帮助将图像转换为带有用于解析 jpeg 和 png 的库的 ImageData 格式。谢谢。将尝试您的示例并应用答案
  • @Kaiido 应用了您的解决方案并提供了一些更新。谢谢!

标签: javascript encryption qr-code rgba


【解决方案1】:

对于second library,我错过了它期望ImageData 并且我传递了二进制数据。

因此,我们有 3 个解决方案如何将二进制数据转换为ImageData

  1. 使用带有一些更新的 createImageBitmap Kaiido 解决方案,因为 cmets 中提出的建议不起作用。
qrCodeUploadedHandler(files: FileList): void {
  const file: File = files[0];

  createImageBitmap(files[0])
    .then(bmp  => {
      const canvas = document.createElement('canvas');

      const width: number = bmp.width;
      const height: number = bmp.height;
      canvas.width = bmp.width;
      canvas.height = bmp.height;

      const ctx = canvas.getContext('2d');

      ctx.drawImage(bmp, 0, 0);
      const qrCodeImageFormat = ctx.getImageData(0,0,bmp.width,bmp.height);
      const qrDecoded = jsQR(qrCodeImageFormat.data, qrCodeImageFormat.width, qrCodeImageFormat.height);
    });
}
  1. 从画布中获取ImageData
qrCodeUploadedHandler(files: FileList): void {
  const file: File = files[0];
  const fileReader: FileReader = new FileReader();
  fileReader.readAsDataURL(files[0]);

  fileReader.onload = (event: ProgressEvent) => {
    const img: HTMLImageElement = new Image();
    img.onload = () => {
      const canvas: HTMLCanvasElement = document.createElement('canvas');
      const width: number = img.width;
      const height: number = img.height;

      canvas.width = width;
      canvas.height = height;

      const canvasRenderingContext: CanvasRenderingContext2D = canvas.getContext('2d');
      console.log(canvasRenderingContext);

      canvasRenderingContext.drawImage(img, 0, 0);

      const qrCodeImageFormat: ImageData = canvasRenderingContext.getImageData(0, 0, width, height);

      const qrDecoded = jsQR(qrCodeImageFormat.data, qrCodeImageFormat.width, qrCodeImageFormat.height);
      canvas.remove();
    };
    img.onerror = () => console.error('Upload file of image format please.');
    img.src = (<any>event.target).result;
}
  1. 您可以使用png.jsjpeg-js 库为ImageData 解析图像。

【讨论】:

    猜你喜欢
    • 2012-11-14
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 2021-03-02
    • 1970-01-01
    • 1970-01-01
    • 2018-09-11
    相关资源
    最近更新 更多