2016-05-03 15 views
2

Unten ist der Code, den ich versuche, aber outofmemory Ausnahme.Fehler Out outmemory beim Beschneiden von Bild

Ich versuche, Bild von nur einem Element aus einem Screenshot durch Selen zu schneiden.

  byte[] image= driver.GetScreenshot().AsByteArray; 
       using (MemoryStream sourceStream = new MemoryStream(image)) 
       { 
        using (Bitmap source = new Bitmap(sourceStream)) 
        { 

         Rectangle cropzone = new Rectangle(element.Location.X, element.Location.Y, element.Size.Width, element.Size.Height); 
         using (Bitmap croppedBitmap = source.Clone(cropzone, source.PixelFormat)) 
         { 
          croppedBitmap.Save(file_name, System.Drawing.Imaging.ImageFormat.Png); 
         } 
        } 
       } 
+0

die Linie, diese Ausnahme zu werfen? –

+0

mit (Bitmap croppedBitmap = source.Clone (cropzone, source.PixelFormat)) – Sid

+1

überprüfen Sie diese bitte http://stackoverflow.com/questions/11467528/outofmemory-exception-when-cropopping-an- image?rq=1 –

Antwort

0

verwendete ich für Sie Selen dies mein Code Aktie zu arbeiten:

public static Bitmap GetEntereScreenshot(IWebDriver driver) 
     { 
      Bitmap stitchedImage = null; 
      try 
      { 
       var jse = (IJavaScriptExecutor)driver; 
       jse.ExecuteScript("window.scrollTo(0, 0);"); 

       var jqueryLibrary = TestExtensions.GetConfigValue("jquery_library", ""); 
       var js = new JqueryExtension(driver, jqueryLibrary); 
       var driverBrowser = ((RemoteWebDriver)driver).Capabilities.BrowserName; 
       //driver_browser= 1: Internet Explorer, 2: Firefox, 3: Google Chrome 
       int totalWidth; 
       int totalHeight; 
       if (driverBrowser.Equals("internet explorer")) 
       { 
        var totalwidth1 = (Int64)((IJavaScriptExecutor)driver).ExecuteScript("return document.body.offsetWidth;"); 
        var totalHeight1 = (Int64)((IJavaScriptExecutor)driver).ExecuteScript("return document.body.parentNode.scrollHeight;"); 
        totalWidth = (int)totalwidth1; 
        totalHeight = (int)totalHeight1; 
       } 
       else 
       { 
        totalWidth = js.GetSizePage("$(document).width();"); 
        totalHeight = js.GetSizePage("$(document).height();"); 
       } 

       // Get the Size of the Viewport 
       var viewportWidth1 = js.GetSizePage("$(window).width();"); 
       //var viewportHeight1 = driverBrowser == "2" ? totalHeight : js.GetSizePage("$(window).height();"); 
       int viewportHeight1; 

       switch (driverBrowser) 
       { 
        case "internet explorer": 
         if (((RemoteWebDriver)driver).Capabilities.Version == "8" || ((RemoteWebDriver)driver).Capabilities.Version == "9") 
         { 
          viewportHeight1 = totalHeight; 
         } 
         else 
         { 
          viewportHeight1 = js.GetSizePage("$(window).height();"); 
         } 
         break; 
        case "firefox": 
         viewportHeight1 = totalHeight; 
         break; 
        default: 
         viewportHeight1 = js.GetSizePage("$(window).height();"); 
         break; 
       } 

       var viewportWidth = viewportWidth1; 
       var viewportHeight = viewportHeight1; 
       // Split the Screen in multiple Rectangles 
       var rectangles = new List<Rectangle>(); 
       // Loop until the Total Height is reached 
       for (var i = 0; i < totalHeight; i += viewportHeight) 
       { 
        var newHeight = viewportHeight; 

        // Fix if the Height of the Element is too big 
        if (i + viewportHeight > totalHeight) 
        { 
         newHeight = totalHeight - i; 
        } 
        // Loop until the Total Width is reached 
        for (var ii = 0; ii < totalWidth; ii += viewportWidth) 
        { 
         var newWidth = viewportWidth; 
         // Fix if the Width of the Element is too big 
         if (ii + viewportWidth > totalWidth) 
         { 
          newWidth = totalWidth - ii; 
         } 

         // Create and add the Rectangle 
         var currRect = new Rectangle(ii, i, newWidth, newHeight); 
         rectangles.Add(currRect); 
        } 
       } 
       // Build the Image 
       stitchedImage = new Bitmap(totalWidth, totalHeight); 
       // Get all Screenshots and stitch them together 
       var previous = Rectangle.Empty; 
       foreach (var rectangle in rectangles) 
       { 
        // Calculate the Scrolling (if needed) 
        if (previous != Rectangle.Empty) 
        { 
         var xDiff = rectangle.Right - previous.Right; 
         var yDiff = previous.Height;//rectangle.Bottom - previous.Bottom; 
         ((IJavaScriptExecutor)driver).ExecuteScript(String.Format("window.scrollBy({0}, {1})", xDiff, yDiff)); 

         System.Threading.Thread.Sleep(500); 
        } 

        // Take Screenshot 
        var screenshot = ((ITakesScreenshot)driver).GetScreenshot(); 

        // Build an Image out of the Screenshot 
        Image screenshotImage; 
        using (var memStream = new MemoryStream(screenshot.AsByteArray)) 
        { 
         screenshotImage = Image.FromStream(memStream); 
        } 

        // Calculate the Source Rectangle 
        var sourceRectangle = new Rectangle(viewportWidth - rectangle.Width, viewportHeight - rectangle.Height, rectangle.Width, rectangle.Height); 

        // Copy the Image 
        using (var g = Graphics.FromImage(stitchedImage)) 
        { 
         g.DrawImage(screenshotImage, rectangle, sourceRectangle, GraphicsUnit.Pixel); 
        } 
        // Set the Previous Rectangle 
        previous = rectangle; 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex); 
      } 
      return stitchedImage; 
     } 
+0

muss ich jedes Paket für TestExtensions und JqueryExtension importieren? – Sid

+0

ja, es wird alle Ihre Seite screenen. das ist "jquery.min.js" https://jquery.com/download/ –

+0

Muss ich das in das Projekt einbeziehen? – Sid

2

Die Out of memory Ausnahme ausgelöst wird, wenn das Beschnittrechtecks ​​außerhalb des Screenshots ist. Wenn der Screenshot die ganze Seite enthält, muss das Element mit einer Position relativ zur Seite zugeschnitten werden. Wenn nicht, muss das Zielelement in die Ansicht gescrollt und mit einer Position relativ zur Ansicht abgeschnitten werden. Hier

ist eine Erweiterung Methode einen Screenshot von einem WebElement zu nehmen:

static class WebElementExt { 

    public static Bitmap TakeScreenshot(this OpenQA.Selenium.IWebElement element) { 
     RemoteWebDriver driver = (RemoteWebDriver)((RemoteWebElement)element).WrappedDriver; 

     if (((IHasCapabilities)driver).Capabilities.HasCapability("takesElementScreenshot")) { 

      byte[] bytes = ((RemoteWebElement)element).GetScreenshot().AsByteArray; 
      return (Bitmap)Bitmap.FromStream(new MemoryStream(bytes, 0, bytes.Length, false, true), false, false); 

     } else { 
      var dict = (Dictionary<String, Object>)driver.ExecuteScript(@" 
       arguments[0].scrollIntoView(true); 
       var r = arguments[0].getBoundingClientRect(), scrollX = 0, scrollY = 0; 
       for(var e = arguments[0]; e; e=e.parentNode) { 
        scrollX += e.scrollLeft || 0; 
        scrollY += e.scrollTop || 0; 
       } 
       return {left: r.left|0, top: r.top|0, width: r.width|0, height: r.height|0 
         , scrollX: scrollX, scrollY: scrollY, innerHeight: window.innerHeight}; " 
       , element); 

      var rect = new System.Drawing.Rectangle(
       Convert.ToInt32(dict["left"]), 
       Convert.ToInt32(dict["top"]), 
       Convert.ToInt32(dict["width"]), 
       Convert.ToInt32(dict["height"])); 

      byte[] bytes = driver.GetScreenshot().AsByteArray; 
      using (Bitmap bitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(bytes, 0, bytes.Length, false, true), false, false)) { 

       if (bitmap.Height > Convert.ToInt32(dict["innerHeight"])) 
        rect.Offset(Convert.ToInt32(dict["scrollX"]), Convert.ToInt32(dict["scrollY"])); 

       rect.Intersect(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height)); 
       if (rect.Height == 0 || rect.Width == 0) 
        throw new WebDriverException("WebElement is outside of the screenshot."); 

       return bitmap.Clone(rect, bitmap.PixelFormat); 
      } 
     } 
    } 
} 

Und ein Anwendungsbeispiel:

var driver = new FirefoxDriver(); 
driver.Navigate().GoToUrl("http://stackoverflow.com"); 

driver.FindElementById("svnrev") 
     .TakeScreenshot() 
     .Save(@"screenshot-element.png", ImageFormat.Png); 

driver.Quit(); 
+0

Du bist mein Held !!!))) Nur eine Anmerkung. Eine Zeile musste geändert werden, da der Build fehlgeschlagen ist.var dict = driver.ExecuteJavaScript > (@ ' – mdementev

Verwandte Themen