0

I've this piece of code which is generating me an QR code, from an input field, and than saving it as .svg.

observeEvent(input$safe_qr,{
  qr <- qr_code(input$qr_gen)
  generate_svg(qr, "QR_Code.svg",
               size = 100,
               foreground = "black",
               background = "white",
               show = interactive())
  renderPlot(qr)
}) 

Now I don't really need to save it, I want to see it next to my input field on the page. I have no idea how put an image inside the page.

One thing I was trying was Plot(qr) then a new window opened in edge and showed me the saved QR code. But yeah that's not what I want.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
  • I assume this has to do with shiny? It's easier to help you if you provide a [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. – MrFlick Jul 19 '22 at 13:20

1 Answers1

1

Here's a working shiny app to allow arbitrary QR generate (of text), showing in both SVG and PNG.

library(shiny)
ui <- fluidPage(sidebarLayout(
  sidebarPanel(
    textInput("text", label = NULL, placeholder = "(some phrase)"),
    imageOutput("svgplot")
  ),
  mainPanel(
    plotOutput("plot")
  )
))

server <- function(input, output, session) {
  QR <- eventReactive(input$text, {
    qrcode::qr_code(input$text)
  })
  output$svgplot <- renderImage({
    txt <- isolate(input$text)
    tf <- tempfile(fileext = ".svg")
    qrcode::generate_svg(QR(), tf, size = 100, foreground = "black", background = "white", show = FALSE)
    list(
      src = normalizePath(tf),
      contentType = "image/svg+xml",
      width = 100, height = 100,
      alt = paste("My QR code:", sQuote(txt, FALSE))
    )
  }, deleteFile = TRUE)
  output$plot <- renderPlot({ plot(QR()) })
}

shinyApp(ui, server)

shiny app with QR svg and png

You don't need to show both, I thought I'd compare/contrast how to show them since they require different steps.

Key takeaways:

  • renderImage allows us to show an arbitrary image that the browser should support. The expression in this call must be a list with the attributes for the HTML img attribute, so here my list(...) is creating

    <img src="path/to/tempfile.svg" contentType="image/svg+xml" width=100 height=100 alt="...">
    
  • I'm doing a two-step here: create the QR object as reactive data, and then anything that will use that will depend on QR() (my QR object). This way there will be fewer reactive-chain calls. This may not be strictly necessary if all you're doing is showing a single QR code, over to you.

  • shiny::renderImage requires the deleteFile= argument; if all you want to is show it, this is fine; if the user wants to right-click on the displayed SVG file and download it locally, it's still fine. In fact, since the "link" text is data:image/svg+xml;base64,PD94bWwgdmVy... and is a fairly long string (39K chars in one example), even if the temp file is deleted, this link remains unchanged and working.

r2evans
  • 141,215
  • 6
  • 77
  • 149
  • Wow thank you thats pretty nice!! Bow my input field will be filled by a qr code reader, and the qr code contains two string seperated by a ";". The first part of the string is used for something else and just the second part should build the new qr code. So i tried something with the strsplit but i achieved not so much –  Jul 20 '22 at 05:55
  • I'm a little confused. Your question is about displaying a QR code, this does it in two ways. What is the connection to `strsplit`? – r2evans Jul 20 '22 at 11:45
  • I have for the Use Case an object with a QR,code on it. This QR Code contains two strings seperated with an ";". So now when the scanner scans an QR_Code it should split the readed the strings at the seperator. The first string now should perform something thats already working and the second part should create me the new QR-Code and display it next to the input field. –  Jul 20 '22 at 12:49
  • Your question asks about *displaying* a QR code that you generate. Your comment here talks about *scanning* and *interpreting* a QR code that is perhaps generated somewhere else and somehow its image scanned into R/shiny. Please clarify, either by editing your question or by correcting my interpretation here. – r2evans Jul 20 '22 at 13:00