Let's say I have the following HTML viewed in the Viewer Pane
tempDir <- tempfile() dir.create(tempDir) htmlFile <- file.path(tempDir, "index.html") write('<h1> Content</h1>', htmlFile, append = TRUE) write('<h2> Content</h2>', htmlFile, append = TRUE) write('lorem ipsum...', htmlFile, append = TRUE) viewer <- getOption("viewer") viewer(htmlFile) When I have this html in the Viewer Pane, I can click on the "Save as image" button:

And I have the html content as a png, for example :

Is there a way to do this with the command line? I know about rstudioapi::savePlotAsImage(), so I'm looking for a kind of saveViewerAsImage.
Edit: I know we can do this with the {webshot} package, but I'm looking for the RStudio function that does that.
However, RStudio has a built-in method that can be accessed by clicking "Export -> Save as Image" in the viewer pane.
If you're running R through Rstudio, then the easiest way to save your image is to click on the “Export” button in the Plot panel (i.e., the area in Rstudio where all the plots have been appearing). When you do that you'll see a menu that contains the options “Save Plot as PDF” and “Save Plot as Image”.
Here's a proposal. The strategy is the following:
png png from the viewer to R png A canvas image possesses a .toDataURL() method that returns a data URI containing the representation of the image in png format (we also can get a jpeg format).
The html2canvas library can be used to take a screenshot: this library renders the current page as a canvas image.
So, one can combine these two functions in the viewer:
html2canvas png using .toDataURL() However, the html2canvas library uses JavaScript Promises that are not supported by the (Windows version) RStudio viewer: a polyfill is required.
png from the viewer to RThis task can be achieved using WebSockets.
The httpuv package can be used to create a webserver. This server will serve a HTML page that will be opened in the RStudio viewer.
A WebSocket communication is established between the httpuv server and the RStudio viewer.
From the R command line, one can send a WebSocket message to the RStudio viewer: receiving this message, the viewer takes the screenshot and send it back to the server.
I'm sorry, this code is quite long for a SO answer.
library(httpuv) # Initialize variables png <- NULL websocket <- NULL # Download Javascript libraries polyfill_promise <- readLines('https://cdn.jsdelivr.net/npm/es6-promise/dist/es6-promise.auto.min.js') html2canvas <- readLines('https://html2canvas.hertzen.com/dist/html2canvas.min.js') # Configure the httpuv server app <- list( call = function(req) { list( status = 200L, headers = list( 'Content-Type' = 'text/html' ), body = paste0(collapse = "\r\n", c("<!DOCTYPE html>", "<html>", "<head>", # polyfill the RStudio viewer to support JavaScript promises '<script type="text/javascript">', polyfill_promise, "</script>", # use html2canvas library '<script type="text/javascript">', html2canvas, "</script>", "</head>", "<body>", html_body, "</body>", '<script type="text/javascript">', # Configure the client-side websocket connection: 'var ws = new WebSocket("ws://" + location.host);', # When a websocket message is received: "ws.onmessage = function(event) {", # Take a screenshot of the HTML body element " html2canvas(document.body).then(function(canvas) {", # Transform it to png " var dataURL = canvas.toDataURL();", # Send it back to the server " ws.send(dataURL);", " });", "};", "</script>", "</html>" ) ) ) }, # Configure the server-side websocket connection onWSOpen = function(ws) { # because we need to send websocket message from the R command line: websocket <<- ws # when a websocket message is received from the client ws$onMessage(function(binary, message) { png <<- message }) } ) # From your question: html_body <- c( '<h1> Content</h1>', '<h2> Content</h2>', 'lorem ipsum...' ) # Start the server: server <- startDaemonizedServer("0.0.0.0", 9454, app) # Open the RStudio viewer: rstudioapi::viewer("http://localhost:9454") # Wait to see the result... # Send a websocket message from the command line: websocket$send("go") # send any message # Write the png image to disk: writeBin( RCurl::base64Decode( gsub("data:image/png;base64,", "", png), "raw" ), "screenshot.png" ) # Close the websocket connection websocket$close() # Stop the server stopDaemonizedServer(server)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With