以下是我正在尝试的代码,但是会出现内存异常。
我正在尝试从通过硒获取的屏幕截图中仅裁剪元素的图像。
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 :(得分: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();
答案 1 :(得分:0)
我曾经为我的代码共享工作selenium:
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;
}