How to change 'Maximum upload size exceeded' restriction in Shiny and save user file inputs?
Quoting Joe Cheng from this shiny-discuss post
By default, Shiny limits file uploads to 5MB per file. You can modify this limit by using the shiny.maxRequestSize option. For example, adding options(shiny.maxRequestSize=30*1024^2) to the top of server.R would increase the limit to 30MB.
Changing the size and storing an image file uploaded by the user with Shiny
We can use magick::image_scale()
to resize the images and then save them in the working directory (or maybe create temp files) because drive_update
takes a path as media
argument.
Version avoiding code repetitions:
library(shiny)
library(magick)
library(tidyverse)
library(googledrive)
n_showphotos <- 3
ui <- fluidPage(
fileInput("loadphotos", label = "Carregar fotos", multiple = TRUE),
actionButton("do", "Carregar"),
tagList(
map(str_c('showphotos', 1:n_showphotos), ~imageOutput(.x, height = '200px')))
)
server <- function(input, output, session) {
observeEvent(input$do, {
lst <- NULL
for (i in 1:length(input$loadphotos[,1])) {
lst[[i]] <- input$loadphotos[[i, 'datapath']]
}
lst %>%
map2(str_c('showphotos', 1:length(.)),~ { output[[.y]] <- renderImage({list(src = .x, height="200")},deleteFile = FALSE) })
#a list with all the images but resized to 200
#"x200" to resize by height
images_resized <- lst %>%
map(~image_scale(image = image_read(.x), "200"))
#images will be located in the project directory or home folder (getwd() to get working directory if in doubt)
images_resized %>%
walk2(str_c('image', 1:length(.)), ~ image_write(.x, path = str_c(.y, '.png'), format = "png"))
# drive_upload(image1.png,
# as_id("https://drive.google.com/drive/u/1/folders/1qj0eeee...")
})
}
shinyApp(ui, server)
With code repetition:
library(tidyverse)
library(googledrive)
library(shiny)
library(magick)
ui <- fluidPage(
fileInput("loadphotos", label="Carregar fotos", multiple=T),
actionButton("do", "Carregar"),
imageOutput("showphotos1", height="200px"),
imageOutput("showphotos2", height="200px"),
imageOutput("showphotos3", height="200px")
)
server <- function(input, output, session) {
observeEvent(input$do, {
lst <- NULL
req(input$loadphotos)
for(i in 1:length(input$loadphotos[,1])) {
lst[[i]] <- input$loadphotos[[i, 'datapath']]
}
output$showphotos1 <- renderImage({list(src=lst[[1]], height="200")})
output$showphotos2 <- renderImage({list(src=lst[[2]], height="200")})
output$showphotos3 <- renderImage({list(src=lst[[3]], height="200")})
images_resized <- NULL
for (i in 1:length(lst)) {
image_scale(image = image_read(lst[[i]]), '200') %>%
image_write(path = str_c('image', i, '.png'), format = "png")
}
#image1.png ... image3.png are available in the working directory.
# drive_upload(image1,
# as_id("https://drive.google.com/drive/u/1/folders/1qj0eeee...")
})
}
shinyApp(ui, server)
Edit:
Adjust ui based on the number of images uploaded by the user.
library(shiny)
library(magick)
library(tidyverse)
library(googledrive)
ui <- fluidPage(
fileInput("loadphotos", label = "Carregar fotos", multiple = TRUE),
actionButton("do", "Carregar"),
uiOutput('images_outputs')
)
server <- function(input, output, session) {
observeEvent(input$do, {
lst <- NULL
for (i in 1:length(input$loadphotos[,1])) {
lst[[i]] <- input$loadphotos[[i, 'datapath']]
}
output$images_outputs <- renderUI({
tagList(
map(str_c('showphotos', 1:length(lst)), ~imageOutput(.x, height = '200px')))
})
lst %>%
map2(str_c('showphotos', 1:length(.)),~ { output[[.y]] <- renderImage({list(src = .x, height="200")},deleteFile = FALSE) })
#a list with all the images but resized to 200
#"x200" to resize by height
images_resized <- lst %>%
map(~image_scale(image = image_read(.x), "200"))
#images will be located in the project directory or home folder (getwd() to get working directory if in doubt)
images_resized %>%
walk2(str_c('image', 1:length(.)), ~ image_write(.x, path = str_c(.y, '.png'), format = "png"))
# drive_upload(image1.png,
# as_id("https://drive.google.com/drive/u/1/folders/1qj0eeee...")
})
}
shinyApp(ui, server)
note: It may be needed to adjust the maximum file size accepted by shiny using options(shiny.maxRequestSize={size})
as shown here
R shiny fileInput large files
Here is an example of using file.choose()
in a shiny app to obtain the local path of the file (and hence the file name):
library(shiny)
ui <- fluidPage(
# Application title
titlePanel("Choosing a file example"),
sidebarLayout(
sidebarPanel(
actionButton("filechoose",label = "Pick a file")
),
mainPanel(
textOutput("filechosen")
)
)
)
server <- function(input, output) {
path <- reactiveValues(
pth=NULL
)
observeEvent(input$filechoose,{
path$pth <- file.choose()
})
output$filechosen <- renderText({
if(is.null(path$pth)){
"Nothing selected"
}else{
path$pth
}
})
}
# Run the application
shinyApp(ui = ui, server = server)
Is this what you're after?
Related Topics
How to Append Rows to an R Data Frame
R: Assign Variable Labels of Data Frame Columns
Do You Use Attach() or Call Variables by Name or Slicing
Calculating Mean for Every N Values from a Vector
How to Learn R as a Programming Language
Access and Preserve List Names in Lapply Function
Libstdc++.So.6: Version 'Glibcxx_3.4.26' Not Found on Linux
Error in Plot.Window(...):Need Finite 'Xlim' Values
Detach All Packages While Working in R
Using Substitute to Get Argument Name
Change Row Order in a Matrix/Dataframe
How to Position Strip Labels in Facet_Wrap Like in Facet_Grid
Comparing Two Vectors in an If Statement
What Are the Differences Between Community Detection Algorithms in Igraph