3
votes

I have part of a shiny function where the user selects the download image type (.png, .tiff etc) and clicks a button to download it. But all options download in .png format and I can't seem to find out what is wrong.

Note that the preview is always png. The download function creates different file types upon clicking the button. Another point to note is the use of file.copy() in downloadhandler rather than something like png(name) plot() dev.off() This is because my plotting function is complex and file.copy() is more practical. The code is below.

#ui.R ----------------------------------------------------------
shinyUI(fluidPage(

  titlePanel("Download test"),

  sidebarLayout(
    sidebarPanel(
      numericInput("fheight", "Height (cm)", min=2, max=15, step=1, value = 10),
      numericInput("fwidth", "Width (cm)", min=2, max=15, step=1, value = 10),
      selectInput("fres", "Res", choices=c("100","200","300"), selected = "100"),
      selectInput("fformat", "File type", choices=c("png","tiff","jpeg","pdf"), selected = "png", multiple = FALSE, selectize = TRUE),
      downloadButton('bn_download', 'Download Plot')
    ),

    # Show a plot of the generated distribution
    mainPanel(
      imageOutput("plotoutput")
    )
  )
))


# server.R ----------------------------------------------------------
shinyServer(function(input, output) {

  # store some values
  store <- reactiveValues(dname="AwesomeDownload")

  # data creation
  fn_data <- reactive({
    df <- data.frame(x=rnorm(50),y=rnorm(50))
  })

  # create filename
  fn_downloadname <- reactive({

    if(input$fformat=="png") filename <- paste0(store$dname,".png",sep="")
    if(input$fformat=="tiff") filename <- paste0(store$dname,".tif",sep="")
    if(input$fformat=="jpeg") filename <- paste0(store$dname,".jpg",sep="")
    if(input$fformat=="pdf") filename <- paste0(store$dname,".pdf",sep="")
    return(filename)
  })

  # render png preview
  output$plotoutput <- renderImage({

    df <- fn_data()
    fheight <- input$fheight
    fwidth <- input$fwidth
    fres <- as.numeric(input$fres)

    png(paste0(store$dname,".png",sep=""), height=fheight, width=fwidth, res=fres, units="cm")
    plot(df)
    dev.off()

    return(list(src = paste0(store$dname,".png",sep=""),
                contentType = "image/png",
                width = round((input$fwidth*as.numeric(input$fres))/2.54, 0),
                height = round((input$fheight*as.numeric(input$fres))/2.54, 0),
                alt = "plot"))
  },deleteFile=TRUE)

  # download function
  fn_download <- function()
    {

    df <- fn_data()
    fheight <- input$fheight
    fwidth <- input$fwidth
    fres <- as.numeric(input$fres)

    if(input$fformat=="pdf") fheight <- round(fheight*0.3937,2)
    if(input$fformat=="pdf") fwidth <- round(fwidth*0.3937,2)

    if(input$fformat=="png") png(fn_downloadname(), height=fheight, width=fwidth, res=fres, units="cm")
    if(input$fformat=="tiff") tiff(fn_downloadname(), height=fheight, width=fwidth, res=fres, units="cm",compression="lzw")
    if(input$fformat=="jpeg") jpeg(fn_downloadname(), height=fheight, width=fwidth, res=fres, units="cm",quality=100)
    if(input$fformat=="pdf") pdf(fn_downloadname(), height=fheight, width=fwidth)
    plot(df)
    dev.off()
  }

  # download handler
  output$bn_download <- downloadHandler(
    filename = fn_downloadname(),
    content = function(file) {
      fn_download()
      file.copy(fn_downloadname(), file, overwrite=T)
    }
  )
})
1

1 Answers

1
votes

Removing parenthesis in the download filename fixed the issue. Yeah, don't even ask. I have no idea why this is so either. But it works.

Joe Cheng's answer:

Change this line:

filename = fn_downloadname(),

to this:

filename = fn_downloadname,