2016-07-14 100 views
8

Sto utilizzando la combinazione di Shiny e knitr per creare documenti PDF.Caricamento di un'immagine nel documento knitr tramite Shiny

Attualmente desidero aggiungere funzionalità che consentiranno all'utente di caricare immagini che verranno inserite all'interno del documento creato. Tuttavia, sono davvero bloccato perché non riesco a ottenere il percorso dell'immagine in ingresso. Qualcuno potrebbe aiutarmi con quello?

semplice esempio:

Applicazione:

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) 

e il documento .Rnw:

\documentclass{article} 

\begin{document} 

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

\end{document} 

Parte '\includegraphics[height=3in]{', picture,'} è ovviamente la causa del problema, perché non si conosce il percorso dell'immagine solo temporanea uno.

+1

percorso del file caricato è 'ingresso $ immagine $ datapath' –

+0

Sì, ma è percorso alla directory temporanea e non ho idea di come farlo funzionare. Inoltre, $ datapath è uguale a [, 4] nel mio codice. –

+0

Prova a sostituire 'paste' con' paste0' nel file '.Rnw', altrimenti c'è uno spazio finale dopo il nome del file e l'immagine non viene trovata. – NicE

risposta

2

hai detto che stavi lavorando con Server Brillante, allora si dovrebbe essere a posto con il percorso completo del immagine, anche se è in una directory temporanea (perché attualmente Shiny Server funziona solo su Linux, e LaTeX dovrebbe andare bene con percorsi di file Linux come /tmp/...../yourfile.png). Il problema è forse il datapath (ad esempio input$picture[, 4]) non ha l'estensione del file, quindi LaTeX non è in grado di riconoscerlo. Puoi provare a recuperare l'estensione del file originale del file e copiare l'immagine caricata in un file temporaneo con la stessa estensione, ad es.

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

La ringrazio molto per la risposta, ma eseguo ancora l'errore 'Running 'texi2dvi' su 'test.tex' non riuscito. Errori LaTeX: ! Errore LaTeX: File '/ tmp/RtmpoSS6qz/4683e6ec5bcf520337300eb1/0' non trovato. Probabilmente mi manca qualcosa di molto semplice ma non riesco a capirlo. –

+0

Inoltre, ho assegnato la funzione reattiva 'picture() 'a semplice' immagine' con 'content = function (file) {picture = pi cture() ' –

+0

Capisco. Mi dispiace, mi sono perso. Aggiornerà la risposta tra un minuto. –

1

vedo una soluzione in due modi:

1) copiare il file temporaneo in una cartella a vostra scelta e l'uso che immagine:

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) se voi (in questo caso la R sessione) non è consentito scrivere su disco è possibile trasformare l'immagine in una variabile base64 e includerla nel documento Knitr (o salvarla in un database come stringa). Questo prende la rotta Knitr/HTML se sei disposto a fare quella deviazione. (Lo studio R in esecuzione da un server ha quasi sempre un sacco di restrizioni nella lettura/scrittura che puoi gestire solo come AMMIN. E il server esegue la sessione lucida come RStudio e non così Rstudio deve avere i permessi di lettura/scrittura necessari se si esegue l'applicazione lucida come una sessione automatica Rstudio lucido e non eseguirlo direttamente da RStudio utilizzando RUN)

assicurarsi che il base64 è leggibile da R ouside il 'osservare' o 'se' portata nuovamente utilizzando '< < - 'insieme a' < - '. Scoping è piuttosto qualcosa di speciale con R quindi assicurati di testarlo correttamente.

Si dovrebbe tuffarsi in questa (base64) con siti come:

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

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

+0

Grazie mille per la risposta. Lavorerò all'implementazione e ti informerò se il tuo approccio mi ha permesso di risolvere il problema. Come hai sottolineato, in realtà sto lavorando con il server Shiny, quindi ci sono problemi con i permessi di scrittura. Ecco perché stavo usando la soluzione fornita [qui] (http://stackoverflow.com/questions/35800883/using-image-in-r-markdown-report-downloaded-from-shiny-app) ma per alcune immagini predefinite che sono posizionati sul server. Mi stavo chiedendo se potrebbe essere applicato a questo caso quando l'immagine viene caricata dall'utente? –

+0

@Un economista, lavorerei sempre con percorsi di sistema completi (a seconda del sistema che parte da ROOT con C:/.... o/.../... o .. e non spero di trovarlo nel cartella stessa o vicina. Può funzionare, ma alcuni programmatori R amano spostare la loro directory di lavoro (con setwd() e getwd() --- >>> non me però = ^) e poi sei al buio .... Tu può, comunque, ottenere sempre la directory del file temporaneo con la funzione call: tempdir() – irJvV