【问题标题】:Qr-code decoder from image file (react native)来自图像文件的二维码解码器(反应原生)
【发布时间】:2025-11-27 20:40:02
【问题描述】:

我正在寻找一种方法来解码图像文件中的 qr 代码,以响应本机(特别是 ios)...我知道 expo 提供相机扫描仪解决方案...但我需要文件解码器

非常感谢任何帮助。

【问题讨论】:

    标签: react-native qr-code expo


    【解决方案1】:

    您可以使用rn-qr-generator 对图像中的二维码进行解码。

    import RNQRGenerator from 'rn-qr-generator';
    
    RNQRGenerator.detect({
      uri: PATH_TO_IMAGE, // local path of the image. Can be skipped if base64 is passed.
      base64: imageBase64String, // If uri is passed this option will be skipped.
    })
      .then(response => {
        const { values } = response; // Array of detected QR code values. Empty if nothing found.
      })
      .catch(error => console.log('Cannot detect QR code in image', error));
    

    它将返回一个检测到的二维码值数组 在 iOS 和 Android 平台上运行良好。

    【讨论】:

    • 嗨@Gev,我在尝试您的解决方案时收到此错误,您知道吗? [TypeError: null is not an object (evaluating 'RNQrGenerator.detect')]
    • @Eddy 您能否提供 rn-qe-generator 版本和您尝试过的平台(iOS、Android)?还有RN版本
    【解决方案2】:

    回答我自己的问题...

    我把我想出的解决方案详细贴了in this blog post

    最后的代码也是Available on Github

    【讨论】:

      【解决方案3】:

      您可以使用jsQR library 从图像文件中读取二维码。要从存储中选择文件,您可以尝试React Native Image Picker library

      【讨论】:

      • 非常感谢...我已经使用 expo ImagePicker 获取 ImageData ...它以 base64 格式返回它,我尝试了许多方法将此 base64 转换为 jsQR 库使用的 Uint8ClampedArray ,但没有工作......有什么建议吗?
      • 我自己没试过,但你应该可以像这样将它转换为 Uint8ClampedArray:new UintClampedArray(Buffer.from(response.data, 'base64'))。我可以稍后测试以确认。
      • 我也试过这个,但不幸的是没有用,如果您有任何解决方案,请帮助
      【解决方案4】:

      也许你可以使用这个react-native-qrcode-local-image

      【讨论】:

        【解决方案5】:

        我假设您正在尝试从图片库/照片中访问图片。

        import * as RNImagePicker from 'expo-image-picker'
        import { BarCodeScanner } from 'expo-barcode-scanner'
        
        const decode = async () => {
          try {
            const { status } = await RNImagePicker.requestMediaLibraryPermissionsAsync()
             if (status === 'granted') {
               const result = RNImagePicker.launchImageLibraryAsync({
                  options: {
                     allowsMultipleSelection: false
                  }
               })
               if (result && result.uri) {
                  const results = await BarCodeScanner.scanFromURLAsync(result.uri)
                  console.log(results) // many information
                  console.log(results.data) // May be the one you are looking for
               }
             }
          } catch (error) {
            console.debug(error)
          }
        }
        

        说明

        • 检查用户是否有权限启动图片库/照片
        • 允许用户选择图像
        • 选择图像后,条码扫描器会为用户溢出信息

        【讨论】:

          【解决方案6】:

          刚刚尝试这样做,几个小时后我可以想出一个解决方案。

          您需要获取图像的 base64 数据,根据图像的格式(PNG/JPEG)将其解码/解析为像素数据,然后将该像素数据转换为 jsqr 使用的 Uint8ClampedArray

          安装以下软件包:

          • pngjs --> 解码 png 图像像素数据(使用浏览器版本)
          • jpeg-js --> 解码jpeg图像像素数据
          • 缓冲区
          • jsqr -> 检测二维码
          • react-native-image-picker(或您选择的图像选择器,但请确保它可以返回 base64 数据)

          npm i pngjs jpeg-js buffer jsqr react-native-image-picker -S

          您可以使用以下代码从图库中的 JPEG 图像中读取 QR 码:

          import jpeg from 'jpeg-js';
          import { Buffer } from 'buffer';
          import { launchImageLibrary } from 'react-native-image-picker';
          import jsQR from 'jsqr';
          const PNG = require('pngjs/browser').PNG;
          
          const readQRFromGallery = () => {
            launchImageLibrary(
                {
                  selectionLimit: 1,
                  mediaType: 'photo',
                  includeBase64: true,
                },
                ({ didCancel, assets, errorCode }) => {
                  if (didCancel || errorCode || !assets || assets.length === 0) {
                   // Handle errors here, or separately
                    return;
                  }
          
                  // Get the image and its base64 data into a buffer
                  const image = assets[0];
                  const base64Buffer = Buffer.from(image.base64!, 'base64');
          
                  let pixelData;
                  let imageBuffer;
                  
                  // Handle decoding based on different mimetypes
                  if (image.type === 'image/jpeg') {
                    pixelData = jpeg.decode(base64Buffer, { useTArray: true }); // --> useTArray makes jpeg-js work on react-native without needing to nodeify it
                    imageBuffer = pixelData.data;
                  } else if (image.type === 'image/png') {
                    pixelData = PNG.sync.read(base64Buffer);
                    imageBuffer = pixelData.data;
                  } else {
                    // you can alert the user here that the format is not supported
                    return;
                  }
          
                  // Convert the buffer into a clamped array that jsqr uses
                  const data = Uint8ClampedArray.from(imageBuffer);
          
                  // Get the QR string from the image
                  const code = jsQR(data, image.width, image.height);
          
                }
              );
            };
          }
          

          我可能在这里遗漏了一些细节,但我认为它应该足以引导您朝着正确的方向前进

          【讨论】:

            最近更新 更多