如何保存闪亮图的 png 图像,使其与我屏幕上的尺寸相匹配?
How to save png image of Shiny plot so it matches the dimensions on my screen?
我用 shiny 绘制了一张图像,并创建了一个保存按钮将图像保存为 .png
文件。
server <- function(input, output) {
output$plot <- renderPlot({
plot(1:500,rep(1:5,100))
})
plotInput <- function(){
plot(1:500,rep(1:5,100))
}
output$savePlot <- downloadHandler(
filename = "file.png",
content = function(file) {
png(file)
plotInput()
dev.off()
}
)
}
当我在我的笔记本电脑屏幕(1366x768 分辨率)上的 Shiny 应用程序中查看图像时,绘图被拉长了(即长于宽度)。 [注:这就是我想要的]。
- 注意:我使用的是
fluidRow
,因此图像会根据我在其上查看的屏幕改变大小。
当我保存绘图时,输出文件不再像在应用程序本身中查看时那样水平长,而是保存为正方形。
现在我知道我可以使用 png()
函数中的 width
、height
和 units
参数修改输出图像的大小。
但是,我不知道我在 Shiny 应用程序中打开的图像的大小。
所以我的问题是:
有没有办法在 Shiny 应用程序中保存图像,使其自动具有与在屏幕上查看时相同的 "dimensions"?
注意:我意识到当我将我的应用程序移动到新的显示器或设备时,图表的 shape/dimensions 会发生变化,因此我正在寻找一些方法来主动确定图像的当前尺寸.
这是我的情节在 在 我笔记本电脑屏幕上的 Shiny 应用程序中的样子:
同样,我希望解决方案能够自动确定屏幕上显示的绘图的当前尺寸,并将这些尺寸应用于我保存的 png
输出图像。
将以下 javascript 添加到您的 UI 中:
tags$script("$(document).on('shiny:connected', function(event) {
var myWidth = $(window).width();
Shiny.onInputChange('shiny_width',myWidth)
});"),
tags$script("$(document).on('shiny:connected', function(event) {
var myHeight = $(window).height();
Shiny.onInputChange('shiny_height',myHeight)
});")
然后,按如下方式更改 downloadHandler
代码:
output$savePlot <- downloadHandler(
filename = "file.png",
content = function(file) {
png(file,
width = input$shiny_width,
height = input$shiny_height)
plotInput()
dev.off()
}
)
您可以使用图像 URI 保存图像。
在这种情况下,图像与您在 shiny 中看到的图像完全相同。
此外,您不需要在 downloadHandler 中重新绘制。
有关详细信息,请查看我在此线程中的回答:
在此处重新发布示例代码:
library(shiny)
library(magick)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
#visibale action button - this button simulates click on hidden download button
actionButton("save_myPlot", "Download", icon = icon("download")),
#hidden download button
downloadButton("save_myPlot_hidden", style = "visibility: hidden;"),
# plot
plotOutput("myPlot")
)
server <- function(input, output, session) {
#get the plot image URI and simulate click on download button
observeEvent(input$save_myPlot, {
shinyjs::runjs(
"
var p_src = document.getElementById('myPlot').childNodes[0].src;
Shiny.setInputValue('plot_src', p_src);
document.getElementById('save_myPlot_hidden').click();
"
)
})
# downaload handler - save the image
output$save_myPlot_hidden <- downloadHandler(
filename = function() {
paste0("plot_", Sys.Date(), ".png") },
content = function(file) {
# get image code from URI
plot_src <- gsub("^data.*base64,", "", input$plot_src)
# decode the image code into the image
plot_image <- image_read(base64_decode(plot_src))
# save the image
image_write(plot_image, file)
})
# plot
output$myPlot <- renderPlot(
plot(rnorm(5), rnorm(5))
)
}
shinyApp(ui = ui, server = server)
我用 shiny 绘制了一张图像,并创建了一个保存按钮将图像保存为 .png
文件。
server <- function(input, output) {
output$plot <- renderPlot({
plot(1:500,rep(1:5,100))
})
plotInput <- function(){
plot(1:500,rep(1:5,100))
}
output$savePlot <- downloadHandler(
filename = "file.png",
content = function(file) {
png(file)
plotInput()
dev.off()
}
)
}
当我在我的笔记本电脑屏幕(1366x768 分辨率)上的 Shiny 应用程序中查看图像时,绘图被拉长了(即长于宽度)。 [注:这就是我想要的]。
- 注意:我使用的是
fluidRow
,因此图像会根据我在其上查看的屏幕改变大小。
当我保存绘图时,输出文件不再像在应用程序本身中查看时那样水平长,而是保存为正方形。
现在我知道我可以使用 png()
函数中的 width
、height
和 units
参数修改输出图像的大小。
但是,我不知道我在 Shiny 应用程序中打开的图像的大小。
所以我的问题是:
有没有办法在 Shiny 应用程序中保存图像,使其自动具有与在屏幕上查看时相同的 "dimensions"?
注意:我意识到当我将我的应用程序移动到新的显示器或设备时,图表的 shape/dimensions 会发生变化,因此我正在寻找一些方法来主动确定图像的当前尺寸.
这是我的情节在 在 我笔记本电脑屏幕上的 Shiny 应用程序中的样子:
同样,我希望解决方案能够自动确定屏幕上显示的绘图的当前尺寸,并将这些尺寸应用于我保存的 png
输出图像。
将以下 javascript 添加到您的 UI 中:
tags$script("$(document).on('shiny:connected', function(event) {
var myWidth = $(window).width();
Shiny.onInputChange('shiny_width',myWidth)
});"),
tags$script("$(document).on('shiny:connected', function(event) {
var myHeight = $(window).height();
Shiny.onInputChange('shiny_height',myHeight)
});")
然后,按如下方式更改 downloadHandler
代码:
output$savePlot <- downloadHandler(
filename = "file.png",
content = function(file) {
png(file,
width = input$shiny_width,
height = input$shiny_height)
plotInput()
dev.off()
}
)
您可以使用图像 URI 保存图像。
在这种情况下,图像与您在 shiny 中看到的图像完全相同。
此外,您不需要在 downloadHandler 中重新绘制。
有关详细信息,请查看我在此线程中的回答:
在此处重新发布示例代码:
library(shiny)
library(magick)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
#visibale action button - this button simulates click on hidden download button
actionButton("save_myPlot", "Download", icon = icon("download")),
#hidden download button
downloadButton("save_myPlot_hidden", style = "visibility: hidden;"),
# plot
plotOutput("myPlot")
)
server <- function(input, output, session) {
#get the plot image URI and simulate click on download button
observeEvent(input$save_myPlot, {
shinyjs::runjs(
"
var p_src = document.getElementById('myPlot').childNodes[0].src;
Shiny.setInputValue('plot_src', p_src);
document.getElementById('save_myPlot_hidden').click();
"
)
})
# downaload handler - save the image
output$save_myPlot_hidden <- downloadHandler(
filename = function() {
paste0("plot_", Sys.Date(), ".png") },
content = function(file) {
# get image code from URI
plot_src <- gsub("^data.*base64,", "", input$plot_src)
# decode the image code into the image
plot_image <- image_read(base64_decode(plot_src))
# save the image
image_write(plot_image, file)
})
# plot
output$myPlot <- renderPlot(
plot(rnorm(5), rnorm(5))
)
}
shinyApp(ui = ui, server = server)