Reputation:
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.
Upvotes: 0
Views: 393
Reputation: 160447
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)
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.
Upvotes: 1