I want to download an image file via XPath using selenium. But I am getting the error that the file was not found.
var resimadresi = driveri.FindElement(By.XPath("/html/body/table[3]/tbody/tr/td/center/table/tbody/tr[2]/td[2]/center/table/tbody/tr[1]/td[4]/table/tbody/tr/td[2]/img"));
WebClient webClient = new WebClient();
webClient.DownloadFile(resimadresi.Text, #"image.png");
You can't do what you want to do with fetchin src of image. Because on every request the image changes. You can take a screenshot of your page and extract the image with some bitmap operations.
void SomeMethod() {
var driver = new ChromeDriver();
driver.Navigate().GoToUrl("https://ebildirge.sgk.gov.tr/WPEB/amp/loginldap");
Screenshot ss = driver.GetScreenshot();
byte[] screenshotAsByteArray = ss.AsByteArray;
Bitmap bmp;
using (var ms = new MemoryStream(screenshotAsByteArray))
{
bmp = new Bitmap(ms);
}
Bitmap cropped = cropAtRect(bmp, new Rectangle(530, 350, 60, 40));
cropped.Save("test.jpeg", ImageFormat.Jpeg);
}
static Bitmap cropAtRect(Bitmap b, Rectangle r)
{
Bitmap nb = new Bitmap(r.Width, r.Height);
Graphics g = Graphics.FromImage(nb);
g.DrawImage(b, -r.X, -r.Y);
return nb;
}
Here is the downloaded image :
Try:
var resimadresi = driveri.FindElement(By.XPath("//td[contains(text(), "Güvenlik Anahtarı")]/following-sibling::node()[img]"));
WebClient webClient = new WebClient();
webClient.DownloadFile(resimadresi.Text, #"image.png");
Güvenlik Anahtarı is the text that I see beside the Verification code, feel free to replace it to whatever you see beside it. There was no translation to english option for me so, I can't really have an accurate text for the xpath.
Related
This is the URL with image-https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/acid.svg
What I have tried
Sample 1-
-I am using SharpVectors package
public void DrawImage()
{
Image svgImage = new Image();
WpfDrawingSettings settings = new WpfDrawingSettings();
settings.IncludeRuntime = false;
settings.TextAsGeometry = true;
FileSvgReader converter = new FileSvgReader(settings);
DrawingGroup drawing = converter.Read(new Uri("https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/acid.svg"));
if (drawing != null)
{
svgImage.Source = new DrawingImage(drawing);
}
}
sample 1 works perfectly but it's latency is very high, So I wanted to improve the performance.
Sample 2 - I tried using bitmap to improve performance below is code, but the issue is I need to download the image or store in folder and use as path as string which works fine but my condition is my URLs are coming form JSON file in .SVG format, they are dynamic and I am not using any .XAMl files for UI.
UI built in code behind programmatically.
Is there any other way I can display SVG image in WPF?
public void DrawImage()
{
Image dynamicImage = new Image();
dynamicImage.Width = 300;
dynamicImage.Height = 200;
stcdock.Children.Add(dynamicImage);
WpfDrawingSettings settings = new WpfDrawingSettings();
settings.IncludeRuntime = true;
settings.TextAsGeometry = false;
string svgTestFile = #"\Downloads\acid.svg";
StreamSvgConverter converter = new StreamSvgConverter(settings);
MemoryStream memStream = new MemoryStream();
if (converter.Convert(svgTestFile, memStream))
{
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = memStream;
bitmap.EndInit();
dynamicImage.Source = bitmap;
}
}
.svg are not nativly supported in wpf.
https://www.nuget.org/packages/svg
This package promisses to add this functionality.
How can I add the url to the screenshot with c# in Selenium. Is there a good solution for this?
I tried the solution. it works and get the url displayed.
Use the steps below to add a URL to a screenshot in Selenium with C#
1- Create a extension:
public static Screenshot AddURLToImage(this Screenshot screenshot, string url)
{
string base64 = String.Empty;
using (var ms = new MemoryStream(screenshot.AsByteArray, 0, screenshot.AsByteArray.Length))
{
Image image = Image.FromStream(ms, true);
Graphics graphics = Graphics.FromImage(image);
using (var font = new Font("Arial", 11))
{
graphics.DrawString(url, font, Brushes.White, 10, 10);
var imageConverter = new ImageConverter();
byte[] buffer = (byte[])imageConverter.ConvertTo(image, typeof(byte[]));
base64 = Convert.ToBase64String(buffer, Base64FormattingOptions.InsertLineBreaks);
}
}
var screenshotWithUrl = new Screenshot(base64);
return screenshotWithUrl;
}
2- Get a screenshot with Selenium
Screenshot screenshot = ((ITakesScreenshot)Driver).GetScreenshot();
3- Add URL to image and save it
screenshot.AddURLToImage(url).SaveAsFile(path);
I have a datagridview with an image column on my form and I set its value to an image in some folder ..
Bitmap PicImage;
PicImage = new Bitmap(ImagePath);
Grid.Rows[i].Cells["ImageColumn"].Value = PicImage;
when I want to delete the row ,the image should be deleted too, but I get "the process cannot access the file..." message :
File.delete(ImagePath);
How can I solve it?
Use a file stream to unlock the file , so instead of:
PicImage = new Bitmap(ImagePath);
use:
using (var stream= new System.IO.FileStream(ImagePath, System.IO.FileMode.Open))
{
var bmp= new Bitmap(stream);
PicImage = (Bitmap) bmp.Clone();
}
Try first to unload the image from the Bitmap and then delete it.
The cleanest method is to load it without any links to files or streams. If it's just for showing on a UI, the simplest way to do this without deep-cloning using LockBits is simply to paint it on a new 32BPP ARGB image:
Bitmap image;
using (Bitmap tmpImage = new Bitmap(filepath))
{
image = new Bitmap(tmpImage.Width, tmpImage.Height, PixelFormat.Format32bppArgb);
using (Graphics gr = Graphics.FromImage(image))
gr.DrawImage(tmpImage, new Rectangle(0, 0, image.Width, image.Height));
}
// Bitmap "image" is now ready to use.
The following code unlinked the datagridview from the image file.
Bitmap timage;
using (Bitmap tmpImage = new Bitmap(tname))
{
timage = new Bitmap(tmpImage.Width, tmpImage.Height, PixelFormat.Format32bppArgb);
using (Graphics gr = Graphics.FromImage(timage))
gr.DrawImage(tmpImage, new Rectangle(0, 0, timage.Width, timage.Height));
}
fileGridView.Rows[dgIndex].Cells["thumbNail"].Value = timage;
I use this code to re-size images, but my problem is that I have to save the original picture then re-size that! How can I re-size a picture without saving it?
I want to re-size the picture first and then save it.
FileUpload1.SaveAs("saveOriginalFileFirstHere");
string thumbpath = "where resized pic should be saved";
MakeThumbnails.makethumb("saveOriginalFileFirstpath", thumbpath);
public static void makethumb(string savedpath, string thumbpath)
{
int resizeToWidth = 200;
int resizeToHeight = 200;
Graphics graphic;
//Image photo; // your uploaded image
Image photo = new Bitmap(savedpath);
// Image photo = new j
Bitmap bmp = new Bitmap(resizeToWidth, resizeToHeight);
graphic = Graphics.FromImage(bmp);
graphic.InterpolationMode = InterpolationMode.Default;
graphic.SmoothingMode = SmoothingMode.Default;
graphic.PixelOffsetMode = PixelOffsetMode.Default;
graphic.CompositingQuality = CompositingQuality.Default;
graphic.DrawImage(photo, 0, 0, resizeToWidth, resizeToHeight);
bmp.Save(thumbpath);
}
Use the InputStream property of the uploaded file instead:
I have modified your code to do so:
EDIT: You really should dispose of your IDisposables, such as your bitmaps and the stream, to avoid memory leakage. I have updated my code, so it will properly dispose these resources after it's done with them.
string thumbpath = "where resized pic should be saved";
MakeThumbnails.makethumb(FileUpload1.InputStream, thumbpath);
public static void makethumb(Stream stream, string thumbpath)
{
int resizeToWidth = 200;
int resizeToHeight = 200;
using (stream)
using (Image photo = new Bitmap(stream))
using (Bitmap bmp = new Bitmap(resizeToWidth, resizeToHeight))
using (Graphics graphic = Graphics.FromImage(bmp))
{
graphic.InterpolationMode = InterpolationMode.Default;
graphic.SmoothingMode = SmoothingMode.Default;
graphic.PixelOffsetMode = PixelOffsetMode.Default;
graphic.CompositingQuality = CompositingQuality.Default;
graphic.DrawImage(photo, 0, 0, resizeToWidth, resizeToHeight);
bmp.Save(thumbpath);
}
}
This should work the way you want it to, if it doesn't, or if anything is unclear, please let me know.
I am trying to create a Bitmap from a stream that has a PDF document saved with-in the stream, but I keep getting argument null exception. The MS is not null and it is positioned at 0. So I'm lost as to what else to do.
I'm testing the functionality by using a windows forms application sandbox but I cannot get the memory stream to save to a Bitmap.
Can someone point out to me where I'm going wrong?
private async void Form1_Load(object sender, EventArgs e)
{
//4355,4373
IElevation elev = await ElevationManager.GetElevationAsync(4355);
PdfSharp.Pdf.PdfDocument pdfDoc =
await (await AlumCloudPlans.Manager.GetLabelsAsync(elev)).GetPDF(new SheetInfo(/*settings for PDF, Img printing is different*/3, 10, 240, 95, 780, 1000));
System.IO.Stream ms = new MemoryStream();
pdfDoc.Save(ms, false);
ms.Position = 0;
Bitmap bm = new Bitmap(ms); <---------(Error right here, says argument null)
this.AutoScroll = true;
this.pictureBox1.Image = bm;
this.pictureBox1.BackColor = Color.White;
this.Size = new System.Drawing.Size(bm.Width, (bm.Height + 50) / 2);
this.pictureBox1.Size = new System.Drawing.Size(bm.Width, bm.Height + 5);
}
What am i missing here?
You're trying to open stream containing a PDF document, Bitmap constructor is expecting image data. PDFSharp can only create PDF document, but can't render it to image.
To render PDF document to bitmap, you have to use other libraries, e.g. lib-pdf, mupdf-converter or .NET wrapper for Ghostscript.