Reputation: 43
I've spent the last days trying to add a button to download an image in my shiny application and I can't get it. I've done it before with other applications, but this one doesn't work. The application chooses two images (or three) and merges them with the transparency you want. The image in the app looks perfect, the problem is only with the download. The server code is as follows;
library(shiny)
library(abind)
library(jpeg)
library(rsconnect)
shinyServer(function(input, output) {
output$myImage <- renderImage({
# A temp file to save the output.
# Return a list containing the filename and alt text
outfile <- tempfile(fileext = '.png')
image1 = jpeg::readJPEG(file.path(
paste(input$map1,'.jpeg', sep='')))
image2 = jpeg::readJPEG(file.path(
paste(input$map2,'.jpeg', sep='')))
image3 = jpeg::readJPEG(file.path(
paste(input$map3,'.jpeg', sep='')))
image1 = abind::abind(image1, image1[,,1]) # add an alpha channel
image1[,,4] = input$trans1 # set alpha to semi-transparent
image2 = abind::abind(image2, image2[,,1]) # add an alpha channel
image2[,,4] = input$trans2
image3 = abind::abind(image3, image3[,,1]) # add an alpha channel
image3[,,4] = input$trans3
if(input$n==0){
png(outfile, width = 4, height = 4, units = 'in', res = 300)
par(mai=c(0,0,0,0))
plot.new()
rasterImage(image1, 0, 0, 1, 1)
rasterImage(image2, 0, 0, 1, 1)
dev.off()
}
if(input$n==1){
png(outfile, width = 2, height = 2, units = 'in', res = 300)
par(mai=c(0,0,0,0))
plot.new()
rasterImage(image1, 0, 0, 1, 1)
rasterImage(image2, 0, 0, 1, 1)
rasterImage(image3, 0, 0, 1, 1)
dev.off()
}
# Return a list containing the filename
list(src = outfile,
contentType = 'image/png',
width = 600,
height = 400,
alt = "This is alternate text")
}, deleteFile = FALSE)
output$downloadImage <- downloadHandler(
filename = "Image.png",
contentType = "image/png",
content = function(file) {
## copy the file from the updated image location to the final download location
file.copy(outfile, file)
}
)
}
The ui code is the following:
library(abind)
library(shiny)
library(rsconnect)
library(jpeg)
library(shiny)
library(shinyBS)
library(shinyjs)
shinyUI(fluidPage(
tags$head(tags$style(
HTML('
#sidebar {
float: right;
background-color: white;
border-bottom: 1px solid #e6e6e6;
border-radius: 0;
}
body, label, input, button, select {
font-family: "Open Sans", Arial, sans-serif;
}')
)),
sidebarLayout(position = "right",
sidebarPanel(
selectInput(inputId = "map1",
label = "Mapa 1:",
choices = c("Mapa 1","Mapa 2","Mapa 3","Mapa 4","Mapa 5"),
selected = "Normal"),
sliderInput(inputId = "trans1",
label = "Transparencia mapa 1:",
min = 0, max = 1, value = 0.5, step = 0.1),
selectInput(inputId = "map2",label = "Mapa 2:",
choices = c("Mapa 1","Mapa 2","Mapa 3","Mapa 4","Mapa 5"),
selected = "Normal"),
sliderInput(inputId = "trans2",label = "Transparencia mapa 2:",
min = 0, max = 1, value = 0.5, step = 0.1),
hr(),
checkboxInput( "n", "Anadir otro mapa:",FALSE),
hr(),
conditionalPanel(condition = "input.n==1", selectInput(inputId = "map3",label = "Mapa 3:",
choices = c("Mapa 1","Mapa 2","Mapa 3","Mapa 4","Mapa 5"),
selected = "Normal")),
conditionalPanel(condition = "input.n==1", sliderInput(inputId = "trans3",label = "Transparencia mapa 3:",
min = 0, max = 1, value = 0.5, step = 0.1)
)
,
hr()
,
downloadButton('downloadImage', 'Download modified image'),
hr()
),
mainPanel(
imageOutput("myImage")
)
)))
The first thing when I push download, instead of trying to download "Image.png" it says to download the file "downloadImage" without extension. Then if i accept it gives the following error:
Anyobdy knows which is the error? I'm desperated!
Thanks
Upvotes: 1
Views: 570
Reputation: 84519
outfile
is defined inside the renderImage
, and then it does not exist in the downloadHandler
. So define it at the root of your server
function:
shinyServer(function(input, output) {
outfile <- tempfile(fileext = '.png')
output$myImage <- renderImage({
......
Upvotes: 3