I am running the following code to get a logo screenshot but as it seems that location and size of element doesn't work when the element is in iframe. How element screenshot works in iframe ?
using System;
using System.Drawing;
using System.IO;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
var _driver = new ChromeDriver();
_driver.Navigate().GoToUrl("https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe");
_driver.SwitchTo().Frame("iframeResult");
_driver.SwitchTo().Frame(_driver.FindElement(OpenQA.Selenium.By.XPath("//iframe[#src='https://www.w3schools.com']")));
IWebElement element = _driver.FindElement(OpenQA.Selenium.By.XPath("//a[#class='w3schools-logo']"));
Console.WriteLine(element.Location); //Return 0
Console.WriteLine(element.Size); //Return 0
Screenshot sc = ((ITakesScreenshot)_driver).GetScreenshot();
using (var img = Image.FromStream(new MemoryStream(sc.AsByteArray)) as Bitmap)
{
img?.Clone(new Rectangle(element.Location, element.Size), img.PixelFormat).Save(#"C:\test.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
I have found a solution
new Actions(_driver).MoveToElement(element).Build().Perform();
Thread.Sleep(1000);
var sc = ((ITakesScreenshot) _driver).GetScreenshot();
var remoteWebElement = element as RemoteWebElement;
using (var img = Image.FromStream(new MemoryStream(sc.AsByteArray)) as Bitmap)
{
if (remoteWebElement != null)
img?.Clone(new Rectangle(remoteWebElement.LocationOnScreenOnceScrolledIntoView,remoteWebElement.Size), img.PixelFormat).Save(file, ImageFormat.Jpeg);
}
Related
I am attempting to save an embedded shape as an image using C#.
If the object is embedded as an actual image (WMF/JPEG) I can retrieve the image without issue but when the object is an embedded shape or an OLE Object that displays as an image in Word I cannot seem to extract or retrieve said object to then either copy to the clipboard or save said image.
Here is my current code sample; either the object is empty or I get the following error:
System.Runtime.InteropServices.ExternalException: 'A generic error occurred in GDI+.'
Any help is appreciated. Thank you
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace ImageMagickSandboxWinForms
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
public static BitmapSource ConvertBitmap(Bitmap source)
{
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
source.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
public static Bitmap BitmapFromSource(BitmapSource bitmapsource)
{
Bitmap bitmap;
using (var outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapsource));
enc.Save(outStream);
bitmap = new Bitmap(outStream);
}
return bitmap;
}
private void button1_Click(object sender, EventArgs e)
{
string physicsDocLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
physicsDocLocation += #"\[Doc path Here].docx";
var wordApp = new Microsoft.Office.Interop.Word.Application();
var wordDoc = wordApp.Documents.Open(physicsDocLocation);
int iCount = wordDoc.InlineShapes.Count;
for (int i = 1; i < (wordDoc.InlineShapes.Count + 1); i++)
{
var currentInlineShape = wordDoc.InlineShapes[i];
currentInlineShape.Range.Select();
wordDoc.ActiveWindow.Selection.Range.Copy();
BitmapSource clipBoardImage = System.Windows.Clipboard.GetImage();
Bitmap bmpClipImage = BitmapFromSource(clipBoardImage);
string finalPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), #"TestConversions");
finalPath += #"\" + Guid.NewGuid().ToString() + ".jpg";
using (MemoryStream memory = new MemoryStream())
{
using (FileStream fs = new FileStream(finalPath, FileMode.Create, FileAccess.ReadWrite))
{
bmpClipImage.Save(memory, ImageFormat.Jpeg); <<<---- Error happens here.
byte[] bytes = memory.ToArray();
fs.Write(bytes, 0, bytes.Length);
}
}
}
wordDoc.Close();
wordApp.Quit();
}
}
}
i have these code in my library, dunno where i have found that but hope you do the job for you: i am using Clippboard to trap the different images, jus t dont forget, Thread is needed to access Clipboard
for (var i = 1; i <= wordApplication.ActiveDocument.InlineShapes.Count; i++)
{
var inlineShapeId = i;
var thread = new Thread(() => SaveInlineShapeToFile(inlineShapeId, wordApplication));
// STA is needed in order to access the clipboard
// https://stackoverflow.com/a/518724/700926
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
}
// General idea is based on: https://stackoverflow.com/a/7937590/700926
protected static void SaveInlineShapeToFile(int inlineShapeId, Application wordApplication)
{
// Get the shape, select, and copy it to the clipboard
var inlineShape = wordApplication.ActiveDocument.InlineShapes[inlineShapeId];
inlineShape.Select();
wordApplication.Selection.Copy();
// Check data is in the clipboard
if (Clipboard.GetDataObject() != null)
{
var data = Clipboard.GetDataObject();
// Check if the data conforms to a bitmap format
if (data != null && data.GetDataPresent(DataFormats.Bitmap))
{
// Fetch the image and convert it to a Bitmap
var image = (Image) data.GetData(DataFormats.Bitmap, true);
var currentBitmap = new Bitmap(image);
// Save the bitmap to a file
currentBitmap.Save(#"C:\Users\Username\Documents\" + String.Format("img_{0}.png", inlineShapeId));
}
}
}
following if you are using Winform or WPF the clipboard acts differently for an image:
if (Clipboard.ContainsImage())
{
// ImageUIElement.Source = Clipboard.GetImage(); // does not work
System.Windows.Forms.IDataObject clipboardData = System.Windows.Forms.Clipboard.GetDataObject();
if (clipboardData != null)
{
if (clipboardData.GetDataPresent(System.Windows.Forms.DataFormats.Bitmap))
{
System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)clipboardData.GetData(System.Windows.Forms.DataFormats.Bitmap);
ImageUIElement.Source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions());
Console.WriteLine("Clipboard copied to UIElement");
}
}
}
after if its not functionam due to a bug in translation of format, there is this solution . So its infrecnh but its easily to understand the logic of the using of "DeviceIndependentBitmap"
Given an image:
And a watermark:
And the code:
var originalImageBytes = originalFile.FileBytes();
// Draw watermark
using (var ms = new MemoryStream(originalImageBytes))
using(var originalImage = Image.FromStream(ms))
using (var watermark = Image.FromFile(Settings.FSO.RootNonPublicDirectory + "Images/Watermark/Watermark.png"))
using (var g = Graphics.FromImage(originalImage))
{
g.DrawImage(watermark, 0, 0);
using (var msOut = new MemoryStream())
{
originalImage.Save(msOut, ImageFormat.Jpeg);
return msOut.ToArray();
}
}
Produces the following result:
Note, the dimensions are correct but a chunk of the bottom of the image is missing.
Right clicking and save-as saves this image onto my disk, looks corrupted:
Does anyone have any idea what is going on here?
I'm trying to modify a print ticket since many days. :(
Here is the code :
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Printing;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Drawing.Printing;
using System.Drawing;
using System.Xml;
// ....
// Get the ticket
var printQueue = new PrintServer("\\\\NetworkNameHere").GetPrintQueue("PrinterNameHere");
PrintTicket userPrintTicket = printQueue.UserPrintTicket;
// Modify the ticket to print in landscape (or any other option)
var xmlDoc = new XmlDocument();
xmlDoc.Load(userPrintTicket.GetXmlStream());
var manager = new XmlNamespaceManager(xmlDoc.NameTable);
manager.AddNamespace(xmlDoc.DocumentElement.Prefix, xmlDoc.DocumentElement.NamespaceURI);
string xpath = string.Format("//psf:Feature[#name='{0}']/psf:Option", "psk:PageOrientation");
XmlNode node = xmlDoc.SelectSingleNode(xpath, manager);
node.Attributes["name"].Value = "psk:Landscape";
PrintTicket modifiedPrintTicket = null;
using (var stream = new MemoryStream())
{
xmlDoc.Save(stream);
stream.Position = 0;
modifiedPrintTicket = new PrintTicket(stream);
}
System.Printing.ValidationResult result = printQueue.MergeAndValidatePrintTicket(printQueue.UserPrintTicket, modifiedPrintTicket);
printQueue.UserPrintTicket = result.ValidatedPrintTicket;
MessageBox.Show(result.ValidatedPrintTicket.PageOrientation.Value.ToString());
printQueue.Commit();
Byte[] myByteBuffer = UnicodeEncoding.Unicode.GetBytes("This is a test string for the print job stream.");
using (var job = printQueue.AddJob())
using (var stream = job.JobStream)
{
stream.Write(myByteBuffer, 0, myByteBuffer.Length);
stream.Close();
}
The problem :
Look like the ticket is correctly modified, but for some reasons it never use the information specified in the ticket for any option. HELP!!!!
Note that I'm using .Net 4.0 but I get the same result with the new PrintTicket parameter in addJob (4.5) : printQueue.AddJob("xx", result.ValidatedPrintTicket)
Thanks!
I want to show the thumbnail image of url in picture box. here is a code i am trying
var request = WebRequest.Create("http://www.facebook.com");
using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
{
pictureBox1.Image = Bitmap.FromStream(stream);
}
The code is not working, or saying no response
here i have used this tecnique
using System;
using System.Configuration;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Facebook;
using System.Net;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
public Bitmap GenerateScreenshot(string url)
{
// This method gets a screenshot of the webpage
// rendered at its full size (height and width)
return GenerateScreenshot(url, -1, -1);
}
public Bitmap GenerateScreenshot(string url, int width, int height)
{
// Load the webpage into a WebBrowser control
WebBrowser wb = new WebBrowser();
wb.ScrollBarsEnabled = false;
wb.ScriptErrorsSuppressed = true;
wb.Navigate(url);
while (wb.ReadyState != WebBrowserReadyState.Complete) { Application.DoEvents(); }
// Set the size of the WebBrowser control
wb.Width = width;
wb.Height = height;
if (width == -1)
{
// Take Screenshot of the web pages full width
wb.Width = wb.Document.Body.ScrollRectangle.Width;
}
if (height == -1)
{
// Take Screenshot of the web pages full height
wb.Height = wb.Document.Body.ScrollRectangle.Height;
}
// Get a Bitmap representation of the webpage as it's rendered in the WebBrowser control
Bitmap bitmap = new Bitmap(wb.Width, wb.Height);
wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height));
wb.Dispose();
return bitmap;
}
private void button1_Click(object sender, EventArgs e)
{
string pc = textBox1.Text;
Bitmap thumbnail = GenerateScreenshot(textBox1.Text, 1024, 598);
thumbnail = GenerateScreenshot(pc);
// Display Thumbnail in PictureBox control
pictureBox1.Image = thumbnail;
}
I try to get aspect ratio of downloaded images. For this purpose I need height and width, but everytime and everyway I try, I get only 0.0 or NaN. I tried Image and BitmapImage. I tried to set Stretch, one of the sizes in hope the other one will be filled automatically.
Both of them don't have set sizes I can read:
Image image = new Image();
image.Source = new BitmapImage(new Uri(customItem.FullURL, UriKind.Absolute));
BitmapImage bitmap = new BitmapImage(new Uri(customItem.FullURL));
The size of the image is not available until it is open. Test for width and height in the ImageOpened event handler.
Code
var bitmap = new BitmapImage(new Uri(uri));
// ImageOpened fires when image is downloaded and decoded
bitmap.ImageOpened += (s, args) =>
{
var w = bitmap.PixelWidth;
};
// setting the source causes the ImageOpened or ImageFailed event to fire.
// image2 must be in visual tree
image2.Source = bitmap;
You can try using the WebClient as suggested in this answer.
using System.Drawing;
using System.Net;
using System.IO;
using System.Windows.Forms;
WebClient wc = new WebClient();
using (MemoryStream ms = new MemoryStream(wc.DownloadData(customItem.FullURL))) {
Image img = Image.FromStream(ms);
MessageBox.Show(img.Height.ToString() + " -- " + img.Width.ToString());
}
Try this (Just replace my url string with your url string):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Net;
namespace GDI
{
class Program
{
static void Main(string[] args)
{
WebClient wc = new WebClient();
Bitmap bmp = new Bitmap(wc.OpenRead("https://s0.2mdn.net/viewad/3092927/Freedom_AW_D_Zenith_119053_DS_Apple_Pay_Bleachers_300x250.jpg"));
Console.WriteLine("Width=" + bmp.Width.ToString() + ", Height=" + bmp.Height.ToString());
Console.ReadLine();
}
}
}
May be this code will helpful for you:
Image image = System.Drawing.Image.FromFile("\1.jpg"); Console.Write("Width: " + image.Width + ", Height: " + image.Height);