Shiny SelectInput to generate filepath for renderImage - r

I have a series of ".jpg" files within my www folder of my script. I want to have renderImage to render the image with the filename that is named "dateplatform.jpg" based on the inputs (date, platform) of my UI. When I try the script below within my server.r file the app isn't displaying any image. Any thoughts?
ui (partial)
fluidRow(
column(width=12,
imageOutput("platformimage")
)
)
server (partial)
filename <- reactive ({
paste(input$date, input$platform, sep="")
})
output$platformimage <- reactive({
renderImage({
list(src = filename(),
width = 600,
height = 600)
},deleteFile = FALSE)
})

filename has to have at least the extension attached to it, and it's probably safer to normalizePath it:
filename <- reactive({
normalizePath(file.path(paste0(input$date, input$platform, '.jpg')))
})
If this fail, it's probably because of the server can't find the file. Check the path created by filename(), and fix inside file.path()
Hope this helps.

Related

Render image in UI created by r shiny

I am using R to generate an image (png file). How do I use shiny to render it to the ui?
source("#rasterBasePlot.R")
output$spatialMap <- renderImage ({
filename <- PNGFileName
# Return a list containing the filename
list(src = filename)
}, deleteFile = TRUE)
You can simply create a www folder inside your app folder and put the images you want to display there. After that something like the following should be sufficent:
library(shiny)
ui <- fluidPage(
tags$img(
src = "/myimage.png", width = 100
)
)
server <- function(input, output, session) {}
shinyApp(ui, server)
If you want to use folders other than www you can use addResourcePath to add resources to Shiny's web server. Please see this.

renderImage issue on shiny r

I have an issue about this code.
observeEvent(input$next, {
output$mark1 <- renderImage({
return(NULL)
}, deleteFile = FALSE)
})
This code is from the server file on shiny. And the UI file, the code is
imageOutput(
outputId = 'mark1',
inline = TRUE
)
My expectation is, if I click 'next', then the image 'mark1' should disappear.
But I got an error message saying:
Warning: Error in basename: a character vector argument expected
Welcome to SO! Please provide a reprex the next time - this will help to get help.
renderImage needs to return a list with at least a src slot. From the help of renderImage
The expression expr must return a list containing the attributes for the img object on the client web page. For the image to display, properly, the list must have at least one entry, src, which is the path to the image file.
So you have to find a way how to tell shiny not to render the image at all when your button is pressed. A neat way to do so is to use req like in the example below. The button render shows the pic and whenever you press delete it goes away. This is due to the fact that req silently raises an error, which tells shiny not to proceed in the observer/render* function and thus not to show the picture in the first place.
library(shiny)
ui <- fluidPage(imageOutput("pic"),
actionButton("go", "Render Print"),
actionButton("delete", "Remove Pic"))
server <- function(input, output, session) {
toggle_pic <- reactiveVal(FALSE)
observeEvent(input$go, toggle_pic(TRUE), ignoreInit = TRUE)
observeEvent(input$delete, toggle_pic(FALSE), ignoreInit = TRUE)
output$pic <- renderImage({
req(toggle_pic())
outfile <- tempfile(fileext = ".png")
# Generate a png
png(outfile, width=400, height=400)
hist(rnorm(100))
dev.off()
# Return a list
list(src = outfile,
alt = "This is alternate text")
}, deleteFile = TRUE)
}
shinyApp(ui, server)

Excel data distribution with Shiny

I am not good at English, so sentences may be wrong.
I want to distribute excel files prepared in advance to users. Is it possible to realize such a system with shiny? No problem with .zip.
Thank you
ui.R
shinyUI(
fluidPage(
downloadButton('downloadData', 'Excel Download')
)
)
server.R
shinyServer(function(input, output) {
output$downloadData <- downloadHandler(
filename = "distribution.xlsx",
content = "distribution_excel"
)
})
Yes, it is possible and you were nearly there. Below is a minimal working example. I assume that your .xlsx file is located in the same folder as your app.R. Notice that I have created the app in a single R file as opposed to two separate files.
The trick to getting the file to download is to use a function for the content inside of downloadHandler(). Specifically we are using the base function file.copy(). Clicking the button should now download the file: distribution.xlsx. This file can obviously be exchanged with a zip file.
If you want different users to access different Excel files, you can write an additional function inside of your server function that passes the file argument to the downloadHandler().
# Load packages ----
pkgs <- c("shiny")
invisible(lapply(pkgs, require, character.only = TRUE))
# Set up the UI ----
ui <- fluidPage(
# Define your download button
downloadButton(
outputId = "downloadData",
label = "Excel Download"
)
)
# Set up the server side ----
server <- function(input, output, session) {
# Define the download handler with function() for content.
output$downloadData <- downloadHandler(
filename = "distribution.xlsx",
content = function(file) {
file.copy("distribution.xlsx", file)
}
)
}
# Combine into an app ----
shinyApp(ui = ui, server = server)

Get original names of files with a function like fileInput (R shiny)

I want to select some files in the browser like with fileInput in Shiny but I only need their paths as a character and nothing else. I do not want to upload them (but it's no problem if it is done anyway). When I use fileInput the result is a data.frame containing the paths of the files in a temporary folder with the names i.e. 0.csv, 1.txt, 2.pdf ... But I need the original filenames (with or without the full path). Is there any way to achieve this in a fast and 'non-hacky' way?
There is a very important reason why this is not possible: Security
JavaScript has no accress to the file System, so you will not to able to get the full paths of the user. One option is your force your user to use a path, but well... he can lie there of course. Maybe do it like this
You could only use it like this:
library(shiny)
ui <- fluidPage(
tags$h1("Test"),
fileInput("file1", "Choose CSV File",
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv")
),
textInput("path", "Please enter the full path of your file"),
tableOutput("pathtable")
)
server <- function(input, output, session) {
testdf <- reactive({
data.frame(
ID = 1,
file = input$path
)
})
output$pathtable <- renderTable({
if(input$path == "") {
return(NULL)
} else {
testdf()
}
})
}
shinyApp(ui = ui, server = server)
The original names are saved in the variable
input$file1$name
However the "real" data (which is renamed as OP correctly pointed out) can be accessed via
input$file1$datapath
where file1 is the InputId of the function fileInput()

RShiny: Input multiple image files and put them into a table

I'm trying to work on a project in shiny to compare images uploaded by user and that saved in my amazon s3 server.
while downloading from s3, I am using this:
save_object(object=xyz ,bucket = "xyz", file = paste0("www/",xyz,".jpg"))
I'm taking input as:
fileInput("image","upload the image")
My dataframe is like this:
a$name<- xyz
a$server_image<- paste0("<img src=",'"',"xyz.jpg",'"'," ","height=",'"',"300",'"',"></img>")
a$uploaded_image<- paste0("<img src=",'"',input$image$datapath,'"'," ","height=",'"',"300",'"',"></img>")
I'm trying to get output like below.
output$output_table<-DT::renderDataTable({DT::datatable(a,escape = FALSE)})
In this case, the image downloaded from aws s3 into "www/" directory is correctly showed in the table, but there is problem with viewing uploaded image.
I also tried to use file.copy on input$image to copy it to a folder "www", but it also doesn't work when I deploy the app.
How can I view an image taken using fileInput and View without using renderImage?
I'm suspecting that your app renders <img src=... before the file is copied in www.
A solution is to convert the image in its base64 encoding and then to render the table including the image from its base64 string.
library(shiny)
library(DT)
ui <- shinyUI(
fluidPage(
fileInput("image", "upload image"),
DT::dataTableOutput("table")
)
)
server <- shinyServer(function(input, output) {
base64 <- eventReactive(input$image, {
base64enc::dataURI(file=input$image$datapath, mime=input$image$type)
})
output$table <- DT::renderDataTable({
req(input$image)
dat <- data.frame(image = sprintf('<img src=%s height="300"></img>', base64()))
datatable(dat, escape=FALSE)
})
})

Resources