public override EyesScreenshot GetSubScreenshot(Region region, bool throwIfClipped) { logger_.Verbose(nameof(GetSubScreenshot) + "([{0}], {1})", region, throwIfClipped); ArgumentGuard.NotNull(region, nameof(region)); // We calculate intersection based on as-is coordinates. Region asIsSubScreenshotRegion = GetIntersectedRegion(region, CoordinatesTypeEnum.SCREENSHOT_AS_IS); if (asIsSubScreenshotRegion.IsSizeEmpty || (throwIfClipped && !asIsSubScreenshotRegion.Size.Equals(region.Size))) { throw new OutOfBoundsException($"Region [{region}] is out of screenshot bounds [{frameWindow_}]"); } Bitmap subScreenshotImage = BasicImageUtils.Crop(Image, asIsSubScreenshotRegion.ToRectangle()); // The frame location in the sub screenshot is the negative of the // context-as-is location of the region. Point contextAsIsRegionLocation = ConvertLocation(asIsSubScreenshotRegion.Location, CoordinatesTypeEnum.SCREENSHOT_AS_IS, CoordinatesTypeEnum.CONTEXT_AS_IS); Point frameLocationInSubScreenshot = new Point(-contextAsIsRegionLocation.X, -contextAsIsRegionLocation.Y); EyesWebDriverScreenshot result = new EyesWebDriverScreenshot(logger_, driver_, subScreenshotImage, subScreenshotImage.Size, Point.Empty); result.UpdateFrameLocationInScreenshot_(new Point(-region.Location.X, -region.Location.Y)); result.DomUrl = DomUrl; logger_.Verbose("Done!"); return(result); }
public Bitmap GetImage() { byte[] screenshotBytes; Bitmap result; if (eyes_.CachedViewport.IsEmpty) { try { string screenshot64 = (string)jsExecutor_.ExecuteScript("mobile: viewportScreenshot"); screenshotBytes = Convert.FromBase64String(screenshot64); } catch (Exception e) { logger_.Log("Warning: " + e); screenshotBytes = tsInstance_.GetScreenshot().AsByteArray; } result = BasicImageUtils.CreateBitmap(screenshotBytes); } else { screenshotBytes = tsInstance_.GetScreenshot().AsByteArray; Bitmap screenshotBitmap = BasicImageUtils.CreateBitmap(screenshotBytes); eyes_.DebugScreenshotProvider.Save(screenshotBitmap, "DEVICE_ORIGINAL"); result = BasicImageUtils.Crop(screenshotBitmap, eyes_.CachedViewport); } result = BasicImageUtils.ScaleImage(result, eyes_.ScaleRatio); return(result); }
public override Bitmap GetImage() { Bitmap image = base.GetImage(); logger_.Verbose("Bitmap Size: {0}x{1}", image.Width, image.Height); eyes_.DebugScreenshotProvider.Save(image, "ANDROID"); if (eyes_.IsCutProviderExplicitlySet) { return(image); } Size originalViewportSize = GetViewportSize(); logger_.Verbose("logical viewport size: " + originalViewportSize); int imageWidth = image.Width; int imageHeight = image.Height; logger_.Verbose("physical device pixel size: {0}x{1}", imageWidth, imageHeight); float widthRatio = image.Width / (float)originalViewportSize.Width; float height = widthRatio * originalViewportSize.Height; Rectangle cropRect = new Rectangle(0, 0, imageWidth, (int)Math.Round(height)); Bitmap croppedImage = BasicImageUtils.Crop(image, cropRect); image.Dispose(); return(croppedImage); }
private Bitmap CropScreenshot_(Bitmap initialScreenshot, Region regionInScreenshot) { if (!regionInScreenshot.IsSizeEmpty) { Bitmap croppedInitialScreenshot = BasicImageUtils.Crop(initialScreenshot, regionInScreenshot.ToRectangle()); initialScreenshot.Dispose(); initialScreenshot = croppedInitialScreenshot; SaveDebugScreenshotPart_(croppedInitialScreenshot, regionInScreenshot.ToRectangle(), "cropped"); } return(initialScreenshot); }
internal static Bitmap CropIOSImage(Bitmap image, Size originalViewportSize, Logger logger = null) { if (logger == null) { logger = new Logger(); } if (devicesRegions == null) { InitDeviceRegionsTable_(); } int imageWidth = image.Width; int imageHeight = image.Height; logger.Verbose("physical device pixel size: {0}x{1}", imageWidth, imageHeight); if (devicesRegions.TryGetValue(image.Size, out List <Rectangle> resolutions)) { int renderedWidth = resolutions[0].Width; int relevantViewportHeight = (renderedWidth < image.Width) ? originalViewportSize.Height - 21 : originalViewportSize.Height; float widthRatio = renderedWidth / (float)originalViewportSize.Width; float height = widthRatio * relevantViewportHeight; if (Math.Abs(height - image.Height) > 1.5) { Rectangle bestMatchingRect = resolutions[0]; float bestHeightDiff = Math.Abs(bestMatchingRect.Height - height); logger.Verbose("bestMatchingRect: {0} ; bestHeightDiff: {1}", bestMatchingRect, bestHeightDiff); for (int i = 1; i < resolutions.Count; ++i) { Rectangle rect = resolutions[i]; float heightDiff = Math.Abs(rect.Height - height); logger.Verbose("rect: {0} ; heightDiff: {1} ; bestHeightDiff: {2}", rect, heightDiff, bestHeightDiff); if (heightDiff < bestHeightDiff) { bestHeightDiff = heightDiff; bestMatchingRect = rect; logger.Verbose("updated bestHeightDiff to {0} and bestMatchingRect to {1}", bestHeightDiff, bestMatchingRect); } } logger.Verbose("closest crop rect found: {0}", bestMatchingRect); image = BasicImageUtils.Crop(image, bestMatchingRect); } else { logger.Verbose("no crop needed. must be using chrome emulator."); } } return(image); }
public override Bitmap GetImage() { Bitmap image = base.GetImage(); logger_.Verbose("Bitmap Size: {0}x{1}", image.Width, image.Height); eyes_.DebugScreenshotProvider.Save(image, "SAFARI"); if (eyes_.IsCutProviderExplicitlySet) { return(image); } double scaleRatio = eyes_.DevicePixelRatio; Size originalViewportSize = GetViewportSize(); Size viewportSize = new Size( (int)Math.Ceiling(originalViewportSize.Width * scaleRatio), (int)Math.Ceiling(originalViewportSize.Height * scaleRatio)); logger_.Verbose("logical viewport size: " + originalViewportSize); if (userAgent_.OS.Equals(OSNames.IOS)) { image = CropIOSImage(image, originalViewportSize, logger_); } else if (!eyes_.ForceFullPageScreenshot) { Point loc; FrameChain currentFrameChain = eyes_.GetDriver().GetFrameChain(); if (currentFrameChain.Count == 0) { IWebElement scrollRootElement = eyes_.GetCurrentFrameScrollRootElement(); IPositionProvider positionProvider = SeleniumPositionProviderFactory.GetPositionProvider(logger_, StitchModes.Scroll, jsExecutor_, scrollRootElement, userAgent_); loc = positionProvider.GetCurrentPosition(); } else { loc = currentFrameChain.GetDefaultContentScrollPosition(); } loc = new Point((int)Math.Ceiling(loc.X * scaleRatio), (int)Math.Ceiling(loc.Y * scaleRatio)); image = BasicImageUtils.Crop(image, new Rectangle(loc, viewportSize)); } eyes_.DebugScreenshotProvider.Save(image, "SAFARI_CROPPED"); return(image); }
public override EyesScreenshot GetSubScreenshot(Region region, bool throwIfClipped) { Region asIsSubScreenshotRegion = GetIntersectedRegion(region, CoordinatesTypeEnum.SCREENSHOT_AS_IS); if (asIsSubScreenshotRegion.IsSizeEmpty || (throwIfClipped && !asIsSubScreenshotRegion.Size.Equals(region.Size))) { throw new OutOfBoundsException($"Region [{region}] is out of screenshot bounds [{Image.Size}]"); } Bitmap subScreenshotImage = BasicImageUtils.Crop(Image, asIsSubScreenshotRegion.ToRectangle()); EyesImagesScreenshot result = new EyesImagesScreenshot(subScreenshotImage); return(result); }
public override EyesScreenshot GetSubScreenshot(Region subregion, bool throwIfClipped) { logger_.Verbose("GetSubScreenshot([{0}], {1})", subregion, throwIfClipped); ArgumentGuard.NotNull(subregion, nameof(subregion)); if (eyes_.CutProvider != null && !(eyes_.CutProvider is NullCutProvider)) { subregion = new Region(Point.Empty, workingArea_.Size); } Bitmap subScreenshotImage = BasicImageUtils.Crop(Image, subregion.ToRectangle()); subregion = subregion.Offset(workingArea_.Left, workingArea_.Top); EyesAppiumScreenshot result = new EyesAppiumScreenshot(logger_, subScreenshotImage, subregion, eyes_); logger_.Verbose("Done!"); return(result); }
public override Bitmap GetImage() { logger_.Verbose("Getting current position..."); Point loc; double scaleRatio = eyes_.DevicePixelRatio; FrameChain currentFrameChain = eyes_.GetDriver().GetFrameChain(); IPositionProvider positionProvider = null; if (currentFrameChain.Count == 0) { IWebElement scrollRootElement = eyes_.GetCurrentFrameScrollRootElement(); positionProvider = eyes_.GetPositionProvider(logger_, StitchModes.Scroll, jsExecutor_, scrollRootElement, userAgent_); loc = positionProvider.GetCurrentPosition(); } else { loc = currentFrameChain.GetDefaultContentScrollPosition(); } Point scaledLoc = new Point((int)Math.Round(loc.X * scaleRatio), (int)Math.Round(loc.Y * scaleRatio)); Bitmap image = base.GetImage(); EyesWebDriver driver = eyes_.GetDriver(); RectangleSize originalViewportSize = EyesSeleniumUtils.GetViewportSize(logger_, driver); RectangleSize viewportSize = originalViewportSize.Scale(scaleRatio); if (image.Height > viewportSize.Height || image.Width > viewportSize.Width) { //Damn IE driver returns full page screenshot even when not asked to! logger_.Verbose("seems IE returned full page screenshot rather than only the viewport."); eyes_.DebugScreenshotProvider.Save(image, "IE"); if (!eyes_.IsCutProviderExplicitlySet) { Bitmap croppedImage = BasicImageUtils.Crop(image, new Rectangle(scaledLoc, viewportSize)); image.Dispose(); image = croppedImage; } } positionProvider?.SetPosition(loc); return(image); }
private void StitchScreenshot_(Size stitchOffset, IPositionProvider stitchProvider, ICollection <SubregionForStitching> screenshotParts, Bitmap stitchedImage, double scaleRatio, ICutProvider scaledCutProvider, float sizeRatio) { int index = 0; logger_.Verbose($"enter: {nameof(stitchOffset)}: {{0}} ; {nameof(screenshotParts)}.Count: {{1}}, {nameof(scaleRatio)}: {{2}}", stitchOffset, screenshotParts.Count, scaleRatio); Stopwatch stopwatch = Stopwatch.StartNew(); foreach (SubregionForStitching partRegion in screenshotParts) { if (stopwatch.Elapsed > TimeSpan.FromMinutes(5)) { logger_.Log("Still Running..."); // this is so CI systems won't kill the build due to lack of activity. stopwatch.Restart(); } logger_.Verbose("Part: {0}", partRegion); // Scroll to the part's top/left Point partAbsoluteLocationInCurrentFrame = partRegion.ScrollTo; partAbsoluteLocationInCurrentFrame += stitchOffset; Point scrollPosition = new Point( (int)Math.Round(partAbsoluteLocationInCurrentFrame.X * sizeRatio), (int)Math.Round(partAbsoluteLocationInCurrentFrame.Y * sizeRatio)); Point originPosition = stitchProvider.SetPosition(scrollPosition); int dx = scrollPosition.X - originPosition.X; int dy = scrollPosition.Y - originPosition.Y; Point partPastePosition = partRegion.PasteLocation; //partPastePosition.Offset(-fullarea.Left, -fullarea.Top); partPastePosition.Offset(dx, dy); // Actually taking the screenshot. Thread.Sleep(waitBeforeScreenshots_); using (Bitmap partImage = imageProvider_.GetImage()) using (Bitmap cutPart = scaledCutProvider.Cut(partImage)) { Bitmap croppedPart; Rectangle r = partRegion.PhysicalCropArea; if ((r.Width * r.Height) != 0) { croppedPart = BasicImageUtils.Crop(cutPart, r); } else { croppedPart = cutPart; } Rectangle r2 = partRegion.LogicalCropArea; using (Bitmap scaledPartImage = BasicImageUtils.ScaleImage(croppedPart, scaleRatio)) using (Bitmap scaledCroppedPartImage = BasicImageUtils.Crop(scaledPartImage, r2)) using (Graphics g = Graphics.FromImage(stitchedImage)) { debugScreenshotsProvider_.Save(partImage, "partImage-" + originPosition.X + "_" + originPosition.Y); debugScreenshotsProvider_.Save(cutPart, "cutPart-" + originPosition.X + "_" + originPosition.Y); debugScreenshotsProvider_.Save(croppedPart, "croppedPart-" + originPosition.X + "_" + originPosition.Y); debugScreenshotsProvider_.Save(scaledPartImage, "scaledPartImage-" + originPosition.X + "_" + originPosition.Y); debugScreenshotsProvider_.Save(scaledCroppedPartImage, "scaledCroppedPartImage-" + partPastePosition.X + "_" + partPastePosition.Y); logger_.Verbose("pasting part at {0}", partPastePosition); g.DrawImage(scaledCroppedPartImage, partPastePosition); } if (!object.ReferenceEquals(croppedPart, cutPart)) { croppedPart.Dispose(); } debugScreenshotsProvider_.Save(stitchedImage, $"stitched_{index}_({partPastePosition.X}_{partPastePosition.Y})"); index++; } } debugScreenshotsProvider_.Save(stitchedImage, "stitched"); }
public Bitmap Cut(Bitmap image) { Rectangle rect = ToRectangle(image.Size); return(BasicImageUtils.Crop(image, rect)); }
public override Bitmap GetImage() { Bitmap image = base.GetImage(); if (eyes_.CachedSessionDetails != null && eyes_.CachedSessionDetails.TryGetValue("deviceOrientation", out object orientation)) { if ("landscape".Equals(orientation as string, StringComparison.OrdinalIgnoreCase) && image.Width < image.Height) { logger_.Verbose("rotating image..."); image.RotateFlip(RotateFlipType.Rotate270FlipNone); } } logger_.Verbose("Bitmap Size: {0}x{1}", image.Width, image.Height); eyes_.DebugScreenshotProvider.Save(image, "SAFARI"); if (eyes_.IsCutProviderExplicitlySet) { return(image); } double scaleRatio = eyes_.DevicePixelRatio; Size originalViewportSize = GetViewportSize(); Size viewportSize = new Size( (int)Math.Ceiling(originalViewportSize.Width * scaleRatio), (int)Math.Ceiling(originalViewportSize.Height * scaleRatio)); logger_.Verbose("logical viewport size: " + originalViewportSize); Bitmap croppedImage = null; if (userAgent_.IsiOS || "ios".Equals(eyes_.PlatformName, StringComparison.OrdinalIgnoreCase) || (eyes_.CachedSessionDetails.TryGetValue("PlatformName", out object platformName) && "ios".Equals(platformName as string, StringComparison.OrdinalIgnoreCase))) { croppedImage = CropIOSImage(image, originalViewportSize, logger_); } else if (!eyes_.ForceFullPageScreenshot) { Point loc; FrameChain currentFrameChain = eyes_.GetDriver().GetFrameChain(); if (currentFrameChain.Count == 0) { IWebElement scrollRootElement = eyes_.GetCurrentFrameScrollRootElement(); IPositionProvider positionProvider = eyes_.GetPositionProvider( logger_, StitchModes.Scroll, jsExecutor_, scrollRootElement, userAgent_); loc = positionProvider.GetCurrentPosition(); } else { loc = currentFrameChain.GetDefaultContentScrollPosition(); } loc = new Point((int)Math.Ceiling(loc.X * scaleRatio), (int)Math.Ceiling(loc.Y * scaleRatio)); croppedImage = BasicImageUtils.Crop(image, new Rectangle(loc, viewportSize)); } if (croppedImage != null && !ReferenceEquals(croppedImage, image)) { image.Dispose(); image = croppedImage; } eyes_.DebugScreenshotProvider.Save(image, "SAFARI_CROPPED"); return(image); }