I'm using Selenium & Google Chrome Driver to open pages programatically. On each page there is a dynamically generated image which I'd like to download. At the moment, I'm waiting for the page to finish loading, then I grab the image URL and download it using System.Net.WebClient.
That works fine except I'm downloading the images twice - once in the browser, once with WebClient. The problem is that each image is roughly 15MB and downloading twice adds up quickly.
So - is it possible to grab the image straight from Google Chrome?
We can check if an image is displayed on page with Selenium. To verify an image we shall take the help of Javascript Executor. We shall utilize executeScript method to execute the Javascript commands in Selenium. Then pass the command return arguments[0].
We can get the source of an image in Selenium. An image in an html document has <img> tagname. Each image also has an attribute src which contains the source of image in the page. To fetch any attribute in Selenium, we have to use the getAttribute() method.
One way is to get base64 string of the image with javascript that is executed by webdriver. Then you can save base64string of the image to file.
Basically, if your image is
<img id='Img1' src='someurl'>
then you can convert it like
var base64string = driver.ExecuteScript(@"
var c = document.createElement('canvas');
var ctx = c.getContext('2d');
var img = document.getElementById('Img1');
c.height=img.naturalHeight;
c.width=img.naturalWidth;
ctx.drawImage(img, 0, 0,img.naturalWidth, img.naturalHeight);
var base64String = c.toDataURL();
return base64String;
") as string;
var base64 = base64string.Split(',').Last();
using (var stream = new MemoryStream(Convert.FromBase64String(base64)))
{
using (var bitmap = new Bitmap(stream))
{
var filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ImageName.png");
bitmap.Save(filepath, ImageFormat.Png);
}
}
Yes, you do this in several steps:
Sample code - please add your code to catch exceptions
IWebDriver driver = new ChromeDriver();
//replace with the page you want to navigate to
string your_page = "https://www.google.com";
driver.Navigate().GoToUrl(your_page);
ITakesScreenshot ssdriver = driver as ITakesScreenshot;
Screenshot screenshot = ssdriver.GetScreenshot();
Screenshot tempImage = screenshot;
tempImage.SaveAsFile(@"C:\full.png", ImageFormat.Png);
//replace with the XPath of the image element
IWebElement my_image = driver.FindElement(By.XPath("//*[@id=\"hplogo\"]/canvas[1]"));
Point point = my_image.Location;
int width = my_image.Size.Width;
int height = my_image.Size.Height;
Rectangle section = new Rectangle(point, new Size(width, height));
Bitmap source = new Bitmap(@"C:\full.png");
Bitmap final_image = CropImage(source, section);
final_image.Save(@"C:\image.jpg");
the CropImage method was posted by James Hill, How to cut a part of image in C#
but I will add it here as well for clarity
public Bitmap CropImage(Bitmap source, Rectangle section)
{
Bitmap bmp = new Bitmap(section.Width, section.Height);
Graphics g = Graphics.FromImage(bmp);
g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel);
return bmp;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With