You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Shiny WebApp实现手机端二维码扫码读取功能

Shiny Web应用实现手机摄像头扫码方案

你之前用的qrcode库主要用于生成条码,无法直接调用摄像头完成扫码操作。要实现手机端扫码功能,需要结合前端JavaScript条码扫描库,将扫码结果传递给Shiny后端处理。下面是基于ZXing-js的可行实现方案:

实现逻辑

  1. 在Shiny的UI中引入ZXing-js前端扫码库
  2. 借助HTML5的getUserMediaAPI调用手机摄像头,实时渲染画面到页面视频元素
  3. 通过ZXing-js识别视频流中的条码,解码后将结果发送给Shiny Server
  4. Shiny后端接收并处理扫码数据

完整代码示例

library(shiny)

ui <- fluidPage(
  # 引入ZXing-js库
  tags$script(src = "https://unpkg.com/@zxing/library@latest"),
  
  titlePanel("手机条码扫描"),
  fluidRow(
    column(6,
           # 摄像头视频显示区域
           tags$video(id = "video", width = "100%", autoplay = TRUE),
           br(),
           actionButton("start_scan", "开始扫码"),
           actionButton("stop_scan", "停止扫码")
    ),
    column(6,
           h4("扫码结果"),
           verbatimTextOutput("scan_result")
    )
  ),
  
  # 自定义扫码逻辑
  tags$script(HTML('
    let codeReader;
    let currentStream;
    
    // 初始化扫码器
    function initReader() {
      codeReader = new ZXing.BrowserMultiFormatReader();
    }
    
    // 点击"开始扫码"触发
    $("#start_scan").on("click", function() {
      if (!codeReader) initReader();
      
      const videoElement = document.getElementById("video");
      // 从摄像头读取视频流并识别条码
      codeReader.decodeFromVideoDevice(null, videoElement, (result, err) => {
        if (result) {
          // 将解码结果传给Shiny后端
          Shiny.setInputValue("scan_data", result.text);
          // 识别成功后自动停止扫码
          stopScan();
        }
      }).then(stream => {
        currentStream = stream;
      });
    });
    
    // 点击"停止扫码"触发
    $("#stop_scan").on("click", stopScan);
    
    // 停止扫码并关闭摄像头
    function stopScan() {
      if (codeReader) codeReader.reset();
      if (currentStream) {
        currentStream.getTracks().forEach(track => track.stop());
      }
    }
    
    // 页面加载完成后初始化扫码器
    $(document).ready(initReader);
  '))
)

server <- function(input, output, session) {
  # 显示扫码结果
  output$scan_result <- renderPrint({
    req(input$scan_data)
    cat("解码结果:", input$scan_data)
  })
  
  # 会话结束时自动停止扫码
  session$onSessionEnded(function() {
    stopScan <- function() {
      session$sendCustomMessage("stop_scan", list())
    }
    stopScan()
  })
}

shinyApp(ui, server)

注意事项

  • HTTPS要求:浏览器仅允许HTTPS网站调用摄像头,本地开发时可使用runApp(ssl = TRUE)启动应用
  • 权限授权:首次打开页面需用户手动授权摄像头访问权限
  • 条码兼容性:ZXing-js支持QR码、EAN-13、UPC-A等绝大多数常见条码类型
  • 性能优化:识别到条码后自动停止扫描,避免持续占用设备资源

内容的提问来源于stack exchange,提问作者Hrx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 15:48:30