25
$\begingroup$

I have Safari, Opera, Chrome, Firefox and IE installed how might a get a browser screen shot of a set of HTML code from inside Mathematica(for any of those browsers)?

enter image description here

(Image is optional)

The shortest/leanest/fastest approach(within reason) is ideal. For example: Waiting for a website to serve a screen shot is to long. The solution should be local.

 screenshot["<!doctype html><i>Italicized text</i>"]
 screenshot["http://example.com"]

Possible ideas: SWT, HTMLunit ,http://watin.org/, Selenium (fairly certain Selenium will work with right install and code).

$\endgroup$
2
  • $\begingroup$ Or this + JLink $\endgroup$
    – rm -rf
    Mar 15, 2014 at 22:13
  • 1
    $\begingroup$ Ok, very good. Ok, very good. Ok, very good. $\endgroup$
    – user13006
    Mar 16, 2014 at 2:21

2 Answers 2

32
$\begingroup$

Copying my answer from StackOverflow (edit, now updated) ...

If you are on Windows (with .NET), then you could use Mathematica's NETLink functionality in conjunction with the WebBrowser class to capture a screenshot of a web page:

Needs["NETLink`"]
LoadNETType["System.Drawing.Imaging.ImageFormat", AllowShortContext -> False]
LoadNETType["System.Windows.Forms.WebBrowserReadyState", AllowShortContext -> False]

Options[dotNetBrowserScreenshot] = {Width -> 1024, Height -> Automatic};
dotNetBrowserScreenshot[uri_, OptionsPattern[]] :=
  NETBlock @ Module[{browser, bitmap, tempFile, image, bounds}
  , browser = NETNew["System.Windows.Forms.WebBrowser"]
  ; browser@Width = OptionValue[Width]
  ; browser@ScrollBarsEnabled = False
  ; browser@ScriptErrorsSuppressed = True
  ; browser@Navigate[uri]
  ; tempFile = Close@OpenWrite[]
  ; While[browser@ReadyState =!= System`Windows`Forms`WebBrowserReadyState`Complete
    , Pause[0.05]
    ]
  ; bounds = browser@Document@Body@ClientRectangle
  ; browser@Height = OptionValue[Height] /. Automatic -> bounds@Height
  ; bitmap = NETNew["System.Drawing.Bitmap", browser@Width, browser@Height]
  ; browser@DrawToBitmap[bitmap, bounds]
  ; browser@Dispose[]
  ; bitmap@Save[tempFile, System`Drawing`Imaging`ImageFormat`Png]
  ; bitmap@Dispose[]
  ; image = Import[tempFile, "PNG"]
  ; DeleteFile[tempFile]
  ; image
  ]

Sample use:

sample screenshot

The complete web page can be captured by using Height -> Automatic (which is the default). Note that the screenshot is being displayed at reduced magnification.

$\endgroup$
5
  • $\begingroup$ This is exactly what I was looking for! Interestingly though despite being local AbsoluteTiming seems to be reporting around 1s run time. Not terrible but seems like there might be room for improvement. I might try caching the opening of the browser or something to speed it up. $\endgroup$
    – William
    Mar 15, 2014 at 22:34
  • $\begingroup$ @LiamWilliam You might also get a speed-up by extracting the bytes from the .NET bitmap and constructing the Mathematica image directly in memory. This would avoid writing the bitmap to disk and then importing it (Import can be slow). $\endgroup$
    – WReach
    Mar 15, 2014 at 22:47
  • 1
    $\begingroup$ Neat stuff, WReach, +1! $\endgroup$
    – ciao
    Mar 15, 2014 at 22:51
  • $\begingroup$ @LiamWilliam Yes, we have to add browser@ScriptErrorsSuppressed = True. I have updated my answer. $\endgroup$
    – WReach
    Mar 15, 2014 at 23:27
  • $\begingroup$ In case anyone is interested the following code allows you to send HTML to a function that responds with the output. I am posting this because there seems to be a rendering issue if you write to a file like <!doctype html><body>text</body> and then try to render pastebin.com/raw.php?i=ZXi2SsME $\endgroup$
    – William
    Mar 17, 2014 at 21:30
7
$\begingroup$

There is now a built-in way to do this:

WebImage["http://stackoverflow.com"]

enter image description here

session = StartWebSession["Chrome"];
WebExecute[session, "OpenPage" -> "http://stackoverflow.com"];
WebExecute[session, "CapturePage"]

enter image description here

WebExecute[session, "SetWindowSize" -> {600, 400}]
WebExecute[session, "CapturePage"]

enter image description here

$\endgroup$
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.