2016-05-03 14 views
2

以下は私が試しているコードですが、メモリ不足例外が発生しています。画像の切り抜き中にOutofMemoryエラーが発生する

私はセレンを使って撮影したスクリーンショットから要素の画像を切り抜こうとしています。

  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

? –

+0

を使用する(ビットマップcroppedBitmap = source.Clone(cropzone、source.PixelFormat)) – Sid

+1

これをチェックしてくださいhttp://stackoverflow.com/questions/11467528/outofmemory-exception-when-cropping-anage-rq=1 –

答えて

0

私はこのあなたのために私のコードシェアをセレンを仕事に使用:

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

TestExtensionsとJqueryExtensionのパッケージをインポートする必要がありますか? – Sid

+0

はい、あなたのすべてのページを表示します。これは "jquery.min.js" https://jquery.com/download/ –

+0

私はプロジェクトにそれを参照する必要がありますか? – Sid

2

クロップ矩形は、スクリーンショットの外にあるときOut of memory例外が発生します。スクリーンショットにフルページが含まれている場合、要素はページを基準にした位置でトリミングする必要があります。そうでない場合、ターゲット要素はビューにスクロールされ、ビューに関連する位置でトリミングされる必要があります。ここで

WebElementのスクリーンショットを撮るための拡張メソッドです:

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); 
      } 
     } 
    } 
} 

と使用例:この例外をスローライン

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

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

driver.Quit(); 
+0

あなたは私のヒーローです! )))ただ一つの音符。ビルドが失敗したため、1行を修正する必要がありました.'var dict = driver.ExecuteJavaScript >(@ ' – mdementev

関連する問題