{"id":341,"date":"2013-08-16T14:47:50","date_gmt":"2013-08-16T12:47:50","guid":{"rendered":"http:\/\/dev.flauschig.ch\/wordpress\/?p=341"},"modified":"2013-12-12T09:35:38","modified_gmt":"2013-12-12T08:35:38","slug":"get-full-page-screenshot-with-chromedriver-2","status":"publish","type":"post","link":"http:\/\/dev.flauschig.ch\/wordpress\/?p=341","title":{"rendered":"Get full page screenshot with ChromeDriver 2"},"content":{"rendered":"<p>I&#8217;m using Selenium for some browser-controlling stuff and mostly use Chrome with the ChromeDriver. But in Version 2.x, ChromeDriver only takes screenshots for the visible area of the screen.<\/p>\n<p>So I created a Script in C# which scrolls around the page, taking screenshots and then stitches it all together.<\/p>\n<p>The code should be easy to port into other languages.<\/p>\n<pre class=\"lang:c#\">\r\n\/\/ Get the Total Size of the Document\r\nint totalWidth = (int)EvalScript<long>(\"return document.width\");\r\nint totalHeight = (int)EvalScript<long>(\"return document.height\");\r\n\r\n\/\/ Get the Size of the Viewport\r\nint viewportWidth = (int)EvalScript<long>(\"return document.body.clientWidth\");\r\nint viewportHeight = (int)EvalScript<long>(\"return document.body.clientHeight\");\r\n\r\n\/\/ Split the Screen in multiple Rectangles\r\nList<Rectangle> rectangles = new List<Rectangle>();\r\n\/\/ Loop until the Total Height is reached\r\nfor (int i = 0; i < totalHeight; i += viewportHeight)\r\n{\r\n\tint newHeight = viewportHeight;\r\n\t\/\/ Fix if the Height of the Element is too big\r\n\tif (i + viewportHeight > totalHeight)\r\n\t{\r\n\t\tnewHeight = totalHeight - i;\r\n\t}\r\n\t\/\/ Loop until the Total Width is reached\r\n\tfor (int ii = 0; ii < totalWidth; ii += viewportWidth)\r\n\t{\r\n\t\tint newWidth = viewportWidth;\r\n\t\t\/\/ Fix if the Width of the Element is too big\r\n\t\tif (ii + viewportWidth > totalWidth)\r\n\t\t{\r\n\t\t\tnewWidth = totalWidth - ii;\r\n\t\t}\r\n\r\n\t\t\/\/ Create and add the Rectangle\r\n\t\tRectangle currRect = new Rectangle(ii, i, newWidth, newHeight);\r\n\t\trectangles.Add(currRect);\r\n\t}\r\n}\r\n\r\n\/\/ Build the Image\r\nvar stitchedImage = new Bitmap(totalWidth, totalHeight);\r\n\/\/ Get all Screenshots and stitch them together\r\nRectangle previous = Rectangle.Empty;\r\nforeach (var rectangle in rectangles)\r\n{\r\n\t\/\/ Calculate the Scrolling (if needed)\r\n\tif (previous != Rectangle.Empty)\r\n\t{\r\n\t\tint xDiff = rectangle.Right - previous.Right;\r\n\t\tint yDiff = rectangle.Bottom - previous.Bottom;\r\n\t\t\/\/ Scroll\r\n\t\tRunScript(String.Format(\"window.scrollBy({0}, {1})\", xDiff, yDiff));\r\n\t\tSystem.Threading.Thread.Sleep(200);\r\n\t}\r\n\r\n\t\/\/ Take Screenshot\r\n\tvar screenshot = ((ITakesScreenshot)_driver).GetScreenshot();\r\n\r\n\t\/\/ Build an Image out of the Screenshot\r\n\tImage screenshotImage;\r\n\tusing (MemoryStream memStream = new MemoryStream(screenshot.AsByteArray))\r\n\t{\r\n\t\tscreenshotImage = Image.FromStream(memStream);\r\n\t}\r\n\r\n\t\/\/ Calculate the Source Rectangle\r\n\tRectangle sourceRectangle = new Rectangle(viewportWidth - rectangle.Width, viewportHeight - rectangle.Height, rectangle.Width, rectangle.Height);\r\n\r\n\t\/\/ Copy the Image\r\n\tusing (Graphics g = Graphics.FromImage(stitchedImage))\r\n\t{\r\n\t\tg.DrawImage(screenshotImage, rectangle, sourceRectangle, GraphicsUnit.Pixel);\r\n\t}\r\n\r\n\t\/\/ Set the Previous Rectangle\r\n\tprevious = rectangle;\r\n}\r\n\/\/ The full Screenshot is now in the Variable \"stitchedImage\"\r\n<\/pre>\n<p>The EvalScript just executes the Javascript and returns the Value, so it should look like:<\/p>\n<pre class=\"lang:c#\">\r\npublic override T EvalScript<T>(string script)\r\n{\r\n\tIJavaScriptExecutor js = (IJavaScriptExecutor)_driver;\r\n\treturn (T)js.ExecuteScript(script);\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m using Selenium for some browser-controlling stuff and mostly use Chrome with the ChromeDriver. But in Version 2.x, ChromeDriver only takes screenshots for the visible area of the screen. So I created a Script in C# which scrolls around the page, taking screenshots and then stitches it all together. The code should be easy to &hellip; <\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[4,3],"tags":[],"class_list":{"0":"entry","1":"post","2":"publish","3":"author-roemer","4":"post-341","6":"format-standard","7":"category-csharp","8":"category-programming"},"acf":[],"views":16480,"_links":{"self":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/341"}],"collection":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=341"}],"version-history":[{"count":0,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/341\/revisions"}],"wp:attachment":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=341"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=341"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=341"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}