【问题标题】:Uploading picture to the knitr document via Shiny通过 Shiny 将图片上传到 knitr 文档
【发布时间】:2016-07-14 10:31:40
【问题描述】:

我正在使用 Shiny 和 knitr 的组合来创建 PDF 文档。

目前我想添加允许用户上传将放置在创建的文档中的图片的功能。但是,我真的卡住了,因为我无法获取输入图片的路径。有人可以帮我吗?

简单示例:

应用:

library(knitr)
library(shiny)

ui <- fluidPage(

  sidebarLayout(
    sidebarPanel(
      fileInput("picture", label = 'Picture'),
      downloadButton('report', label = 'Download PDF')
      ),

    mainPanel()
  )
)

server <- function(input,output){

  picture <-  reactive({
    input$picture[,4]
  })

  output$report = downloadHandler(
    filename = "test.pdf",

    content = function(file){
      picture = picture()

    out = knit2pdf(input = 'test.Rnw', compiler = 'xelatex', clean = TRUE)
    file.rename(out, file) 
    },

    contentType = 'application/pdf'
  )
}

shinyApp(ui = ui, server = server)

还有.Rnw 文档:

\documentclass{article}

\begin{document}

Put picture here:
<<echo = FALSE , message = F, results='asis'>>=
cat(paste('\\includegraphics[height=3in]{', picture,'}'))
@

\end{document}

部分'\includegraphics[height=3in]{', picture,'}显然是造成问题的原因,因为我不知道图片路径只是临时的一个。

【问题讨论】:

  • 上传文件路径为input$picture$datapath
  • 是的,但它是临时目录的路径,我不知道如何使它工作。此外,$datapath 与我的代码中的 [,4] 相同。
  • 尝试在你的.Rnw文件中将paste替换为paste0,否则文件名后面有一个尾随空格,找不到图片。
  • 我仍然收到错误:running 'texi2dvi' on 'test.tex' failed LaTeX errors: C:/Users/meme/Desktop/test.tex:55: LaTeX Error: File C:/ea9c33bfd57973b840657c82/0' not found.

标签: r shiny knitr


【解决方案1】:

你说你在使用 Shiny Server,那么你应该对图片的完整路径没问题,即使它在临时目录中(因为目前 Shiny Server 只适用于 Linux,而 LaTeX 应该适用于 Linux像/tmp/...../yourfile.png这样的文件路径)。问题可能是datapath(即input$picture[, 4])没有文件扩展名,所以LaTeX 无法识别它。您可以尝试检索原始文件的文件扩展名,并将上传的图片复制到具有相同扩展名的临时文件中,例如

picture <- reactive({
  path1 <- input$picture$datapath
  path2 <- tempfile(fileext = gsub('^(.*)([.].+)$', '\\2', input$picture$name))
  file.copy(path1, path2, overwrite = TRUE)
  path2
})

【讨论】:

  • 非常感谢您的回答,但我仍然运行我到错误Running 'texi2dvi' on 'test.tex' failed. LaTeX errors: ! LaTeX Error: File '/tmp/RtmpoSS6qz/4683e6ec5bcf520337300eb1/0' not found. 我可能遗漏了一些非常基本的东西,但我真的无法弄清楚。
  • 此外,我将反应函数 picture() 分配给简单的 picturecontent = function(file){picture = picture()
  • 我明白了。对不起,我错过了。将在一分钟内更新答案。
  • 无需道歉,非常感谢您的关注和帮助。
  • 虽然在任何地方都使用picture 这个名字有点令人困惑。它是content函数中的输入ID、reactive的名称和实际路径的名称。
【解决方案2】:

我从两个方面看到了解决方案:

1) 将临时文件复制到您选择的文件夹并使用该图像:

observe({
        if (is.null(input$picture)) return()
        picture<-"your/final/path/to/disk/uploadImage.jpg" # OR do a PASTE with the PATH and the upload file name
        file.copy(input$picture$datapath, picture)
        if(file.exists(picture)){
          # PROCESS THE IMAGE IF NEEDED
        }
        picture<<-picture # sometimes needed to R to see the variable outside the observe scope
 })

2) 如果您(在本例中为 R 会话)不允许写入磁盘,您可以将图像转换为 base64 变量并将其包含到您的 Knitr 文档中(或将其作为字符串保存到数据库中)。如果您愿意绕道而行,这将采用 Knitr/HTML 路线。 (从服务器运行的 R Studio 在读/写方面几乎总是有很多限制,您只能作为管理员处理。并且服务器以 RStudio 而不是您运行闪亮会话,因此 Rstudio 必须具有所需的读/写权限,如果您将 Shiny 应用程序作为自动 Rstudio Shiny 会话运行,而不是使用 RUN 直接从 RStudio 运行)

使用 '

您应该通过以下网站深入了解 (base64):

https://github.com/yihui/knitr/issues/944

https://github.com/yihui/knitr/blob/master/R/utils-base64.R

【讨论】:

  • 非常感谢您的回复。我将致力于实施,并让您知道您的方法是否允许我解决问题。正如您所指出的,我实际上正在使用 Shiny 服务器,因此存在写入权限的问题。这就是为什么我使用here 提供的解决方案,但对于放置在服务器上的一些预定义图像。我想知道当用户上传图片时,它是否可以应用于这种情况?
  • @一位经济学家,我总是使用完整的系统路径(取决于系统从 ROOT 开始,使用 C:/.... 或 /.../... 或 .. 和不希望在同一个或附近的文件夹中找到它。可以工作,但一些 R 程序员喜欢移动他们的工作目录(使用 setwd() 和 getwd() --->> 不是我虽然 =^)然后你在盲人....顺便说一句,您总是可以通过函数调用获取临时文件目录:tempdir()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-01
  • 1970-01-01
  • 2018-06-07
  • 1970-01-01
  • 2018-02-22
  • 1970-01-01
  • 2011-10-04
相关资源
最近更新 更多