Taking screenshots of web pages with macruby
Whilst playing around with the very exciting macruby last weekend, I thought I’d try building a web page screenshot grabber, based on Ben Curtis’ code. The code was very easy to change translate from rubycocoa
, looks cleaner and seems to work really well:
framework 'Cocoa'
framework 'WebKit'
class Snapper
attr_accessor :options, :view, :window
def initialize(options = {})
@options = options
initialize_view
end
def save(url, file)
view.setFrameLoadDelegate(self)
# Tell the webView what URL to load.
frame = view.mainFrame
req = NSURLRequest.requestWithURL(NSURL.URLWithString(url))
frame.loadRequest req
while view.isLoading && !timed_out?
NSRunLoop.currentRunLoop.runUntilDate NSDate.date
end
if @failedLoading
puts "Failed to load page at: #{url}"
else
docView = view.mainFrame.frameView.documentView
docView.window.setContentSize(docView.bounds.size)
docView.setFrame(view.bounds)
docView.setNeedsDisplay(true)
docView.displayIfNeeded
docView.lockFocus
bitmap = NSBitmapImageRep.alloc.initWithFocusedViewRect(docView.bounds)
docView.unlockFocus
# Write the bitmap to a file as a PNG
representation = bitmap.representationUsingType(NSPNGFileType, properties:nil)
representation.writeToFile(file, atomically:true)
bitmap.release
end
end
private
def webView(view, didFailLoadWithError:error, forFrame:frame)
@failedLoading = true
end
def webView(view, didFailProvisionalLoadWithError:error, forFrame:frame)
@failedLoading = true
end
def initialize_view
NSApplication.sharedApplication
self.view = WebView.alloc.initWithFrame([0, 0, 1024, 600])
self.window = NSWindow.alloc.initWithContentRect([0, 0, 1024, 600],
styleMask:NSBorderlessWindowMask, backing:NSBackingStoreBuffered, defer:false)
window.setContentView(view)
# Use the screen stylesheet, rather than the print one.
view.setMediaStyle('screen')
# Set the user agent to Safari, to ensure we get back the exactly the same content as
# if we browsed directly to the page
view.setCustomUserAgent 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-us)' +
'AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10'
# Make sure we don't save any of the prefs that we change.
view.preferences.setAutosaves(false)
# Set some useful options.
view.preferences.setShouldPrintBackgrounds(true)
view.preferences.setJavaScriptCanOpenWindowsAutomatically(false)
view.preferences.setAllowsAnimatedImages(false)
# Make sure we don't get a scroll bar.
view.mainFrame.frameView.setAllowsScrolling(false)
end
def timed_out?
@start ||= Time.now
(Time.now.to_i - @start.to_i) > (options[:timeout] || 30)
end
end
To use:
macruby -r snapper.rb -e "Snapper.new.save('http://tomafro.net', 'tomafro.net.png')"
The next step is to add some command line options, then try compilation and deployment with macrubyc
and macruby_deploy