我正在构建一个可让用户将图像上传到服务器的Shiny应用。我想在屏幕上显示图像,而不必先将其上传,然后再将渲染的输出恢复。这可能吗?
这是我现在的代码。您可以选择上传的图像文件。然后,在收到图像后,从服务器端的文件中呈现图像。我想避免往返。
UI
fluidPage(
titlePanel("File upload"),
sidebarLayout(
sidebarPanel(
fileInput("img", "Choose image file",
accept=c("image/jpeg", "image/x-windows-bmp"))
),
mainPanel(
imageOutput("picture", width="500px", height="500px")
)
)
)
服务器
function(input, output, session)
{
output$picture <- renderImage({
imgFile <- input$img
if(is.null(imgFile))
return(list(src=""))
list(src=imgFile$datapath, alt=imgFile$name, contentType=imgFile$type)
}, deleteFile=FALSE)
# do more stuff with the file
}
答案 0 :(得分:3)
您可以使用程序包shinyjs
从HTML 5 read here
FileReader
library(shinyjs)
shinyApp(ui = fluidPage(
useShinyjs(),
titlePanel("File upload"),
sidebarLayout(
sidebarPanel(
fileInput("img", "Choose image file",
accept=c("image/jpeg", "image/x-windows-bmp")),
HTML('<output id="list"></output>')
),
mainPanel(
imageOutput("picture", width="500px", height="500px")
)
)),
server = function(input, output, session){
shinyjs::runjs("
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class=\"thumb\" src=\"', e.target.result,
'\" title=\"', escape(theFile.name), '\"/>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
document.getElementById('img').addEventListener('change', handleFileSelect, false);")
output$picture <- renderImage({
imgFile <- input$img
if(is.null(imgFile))
return(list(src=""))
list(src=imgFile$datapath, alt=imgFile$name, contentType=imgFile$type)
}, deleteFile=FALSE)
})
答案 1 :(得分:1)
修改强>
好的,我现在对我很清楚,我希望:)。
问题是图片是在<output id="list"></output>
内添加的。所以我建议在添加新图片之前清除它:document.getElementById('list').innerHTML = ''
library(shiny)
library(shinyjs)
shinyApp(ui = fluidPage(
useShinyjs(),
titlePanel("File upload"),
sidebarLayout(
sidebarPanel(
fileInput("img", "Choose image file",
accept=c("image/jpeg", "image/x-windows-bmp"))
),
mainPanel(
HTML('<output id="list"></output>')
)
)),
server = function(input, output, session){
shinyjs::runjs("
function handleFileSelect(evt) {
document.getElementById('list').innerHTML = ''
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class=\"thumb\" src=\"', e.target.result,
'\" title=\"', escape(theFile.name), '\"/>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
document.getElementById('img').addEventListener('change', handleFileSelect, false);")
})