Get Captcha Image from Web Browser control without using SRC - c#

I know this question might sound familiar and there are plenty of posts out there on google with the same title BUT trust me this is different.
Editor : VS2008 (cannot upgrade it due to some technical difficulties)
Question
How to get Captcha Image from a Web Browser without using SRC?
Why wouldn't you use SRC?
Here is the site from which i am trying to get my Captcha Image
https://services.gst.gov.in/services/login
(The capta image appears once you type anything in User Name)
Now if you right click on the Captcha Image and go to inspect element you will see that the SRC of the captcha is:-
https://services.gst.gov.in/services/captcha?rnd=0.5313315062651027
and whenever you try to go to that link it will give you a captcha that is different from the previous one. That is why i cant use the below code because it shows different captcha than the one showing in the WebBrowser right now.
HtmlElement element = webBrowser1.Document.GetElementById("imgCaptcha");
string src = element.GetAttribute("src");
pictureBox1.Load(element.GetAttribute("src"));

You can use createControlRange to create a controlRange of non-text elements. Then find the image tag, for example by using id, then add the image tag to the control range and call it's execCommand method to execute Copy command, and finally, get the image from clipboard:
.NET 3.5
Add a reference to MSHTML. You can find it by Microsoft HTML Object Library under COM references and then add using mshtml;. Then:
IHTMLElement2 body = (IHTMLElement2)webBrowser1.Document.Body.DomElement;
IHTMLControlRange controlRange = (IHTMLControlRange)body.createControlRange();
IHTMLControlElement element = (IHTMLControlElement)webBrowser1.Document
.GetElementById("imgCaptcha").DomElement;
controlRange.add(element);
controlRange.execCommand("Copy", false, null);
pictureBox1.Image = (Bitmap)Clipboard.GetDataObject().GetData(DataFormats.Bitmap);
.NET >= 4.0
You don't need to add a reference, you can take advantage of dynamic:
dynamic body = webBrowser1.Document.Body.DomElement;
dynamic controlRange = body.createControlRange();
dynamic element = webBrowser1.Document.GetElementById("imgCaptcha").DomElement;
controlRange.add(element);
controlRange.execCommand("Copy", false, null);
pictureBox1.Image = (Bitmap)Clipboard.GetDataObject().GetData(DataFormats.Bitmap);
Note:
Run the code when the document is completed, for example in DocumentCompleted event.
Also you may want to add null checking to the code.
I used above code to get the google logo from https://www.google.com by id hplogo.
I also tested above code, by browsing https://demos.captcha.com/demos/features/captcha-demo.aspx and finding the captcah image by c_captchademo_samplecaptcha_CaptchaImage as id of the captcha image.

Related

Xamarin Forms: Default Image if Url not found

In xamarin forms we can create images like this:
Image i = new Image { Source = "http://www.foo.com/foo.jpg };
After adding this to layout if url returns an image it will display it. What I want to now is is there a way to know if ths Url is an actual image. Otherwise I am going to show an default image.
Regards.
Edit
I have created a function:
public string GetImageSourceOrDefault(string orgUrl)
{
var req = (HttpWebRequest)WebRequest.Create(orgUrl);
req.Method = "HEAD";
try
{
using (var resp = req.GetResponse())
{
bool res = resp.ContentType.ToLower(CultureInfo.InvariantCulture)
.StartsWith("image/");
if (res)
return orgUrl;
else
return "defualt_logo.jpg";
}
}
catch
{
return "default_logo.jpg";
}
}
This function does the trick. However, for every image it does a request. I have a listview which shows like 220 entries. Using this method messed up the time that listview gets loaded.
Note: this function is natively called using dependency injection.
Maybe further improvements will do. Any ideas?
FFImageLoading CachedImage supports Loading and Error Placeholders (and much more). It's basically a API compatible replacement for Image with additional properties. You could try that.
var cachedImage = new CachedImage() {
LoadingPlaceholder = "Loading.png",
ErrorPlaceholder = "Error.png"
};
https://github.com/molinch/FFImageLoading
With Xamarin.Forms UriImageSource you can specify different caching length, and whether caching is used by using the properties CacheValidity and CachingEnabled.
By default it will automatically cache results for 1 day on the local storage of the device.
In your function, as you mention, you are downloading the image every single time.
You have no current functionality that is storing and caching the result for later re-use.
By implementing something like this on the platform specific layer would get around your current solution of re-downloading the image every single time.
Alternatively as a workaround, if you didn't want to implement the above, you could try putting two Image controls stacked upon each other, maybe in a Grid, with the bottom image showing a default placeholder image, and on-top another Image control that would show the intended image, if successfully downloaded, using the UriImageSource.
You could also possibly hook hook into the PropertyChange notification of the Image.Source and detect it being set, with the image then being displayed. Upon detection you could then release the image from the temporary place holder Image control perhaps?

Copying the content from a WebView under WinRT

I've got a WebView with some HTML content which I want to convert into RTF. I've looked at the RTF conversion functions out there and they all look a little flaky to be honest. So my idea is to copy content from the WebView into a RichEditBox, and save to RTF from there.
I've seen this example numerous times.
WebBrowser1.Document.ExecCommand("SelectAll", false, null);
WebBrowser1.Document.ExecCommand("Copy", false, null);
Unfortunately, WinRT's WebView control doesn't have a Document property, so I can't do this
Is there any way to pull the content from the control? To be clear, I don't want the HTML itself - I can get that already using
InvokeScript("eval", new string[] { "document.getElementById('editor').innerHTML;" });
What I want is the actual rendered HTML - the same as if I were to select everything in my WebView, press CTRL+C and then paste it into wordpad.
This is part of a series of questions I asked in trying to accomplish a bigger task - converting HTML to RTF in a Windows Store App.
I'm delighted to report that the above can be done. I finally figured out how to do it, using DataPackage - normally used for sharing content between apps.
First, this javascript function must exist in the HTML loaded in the webview.
function select_body() {
var range = document.body.createTextRange();
range.select();
}
Next, you'll need to add using Windows.ApplicationModel.DataTransfer; to the top of your document. Not enough StackOverflow answers mention the namespaces used. I always have to go hunting for them.
Here's the code that does the magic:
// call the select_body function to select the body of our document
MyWebView.InvokeScript("select_body", null);
// capture a DataPackage object
DataPackage p = await MyWebView.CaptureSelectedContentToDataPackageAsync();
// extract the RTF content from the DataPackage
string RTF = await p.GetView().GetRtfAsync();
// SetText of the RichEditBox to our RTF string
MyRichEditBox.Document.SetText(Windows.UI.Text.TextSetOptions.FormatRtf, RTF);
I've spent about 2 weeks trying to get this to work. Its such a relief to finally discover I don't have to manually encode the file to RTF. Now if I can just get it to work the other way around, I'll be ecstatic. Not essential to the app I'm building, but it would be a lovely feature.
UPDATE
In retrospect you probably don't need to have the function in the HTML, you could probably get away with this (though I haven't tested):
MyWebView.InvokeScript("execScript", new string[] {"document.body.createTextRange().select();"})

Converting aspx page to image file

I have c# dynamic aspx page after new property add I create for record brochure
http://veneristurkey.com/admin/Brochure.aspx?Admin=PropertiesBrochureA4&id=36
but I want to this convert image file I am searching on internet but all with webbrowser and windows forms. I need on page load show not css type also image file. jpg, png or tiff how i can do this. i need to see sample code..
saving aspx page into an image 2
As I mentioned in my comment, your best bet is to opt for attempting to render HTML to an image.
Here is the link for a library that will allow your to render html to an image:
http://htmlrenderer.codeplex.com/
Here is code that does exactly what you're asking:
http://amoghnatu.wordpress.com/2013/05/13/converting-html-text-to-image-using-c/
Now all you have left is to get the html, since I'm assuming you don't want this to render to the browser prior to generating this image - you should look into grabbing the rendered html from the aspx page on the server prior to returning it, and then just return the image. To render a page:
https://stackoverflow.com/a/647866/1017882
Sorted.
If you do not mind using a commandline tool you can have a look at wkhtmltopdf. The package include a wkhtmltoimage component that can be used to convert HTML to image, using
wkhtmltoimage [URL] [Image Path]
Codaxy also wrote a wkhtmltopdf c# wrapper available through the NuGet package manager. I'm not sure if the wkhtmltoimage component was included, but it should be easy enough to figure out how they wrap the wkhtml components.
i fixed my problem with screenshot machine API they are my code..
public void resimyap()
{
var procad = WS.Satiliklars.Where(v => v.ForSaleID == int.Parse(Request.QueryString["id"])).FirstOrDefault();
var imageBytes = GetBytesFromUrl("http://api.screenshotmachine.com/?key=xxxxxx&size=F&url=http://xxxxxxx.com/a4.aspx?id=" + procad.ForSaleID);
string root = Server.MapPath("~/");
// clean up the path
if (!root.EndsWith(#"\"))
root += #"\";
// make a folder to store the images in
string fileDirectory = root + #"\images\a4en\";
// create the folder if it does not exist
if (!System.IO.Directory.Exists(fileDirectory))
System.IO.Directory.CreateDirectory(fileDirectory);
WriteBytesToFile( fileDirectory + + procad.ForSaleID + ".png", imageBytes);
Yes i also try wkhtmltopdf c# wrapper but in pdf or image converting time my computer fan goin crayz. also i must upload server exe file and my hosting firm didnt support them

WebBrowser Control c#: finding particular link and "clicking" it programmatically?

I am working on csv downloader project ,i need to download the CSV files generated on the webpage . and using html agility , i found the exact link that contain the link for csv file
Download file in csv format
now i want , without any activity from my side , the application must detect this link in the web page ( i could do it by Htmlagility ) and should download the file once the web page fully navigated in Web browser in my app. I tried some example in one of the SO click here post but getting
Error :Object reference not set to an instance of an object.
HtmlElementCollection links = webBrowser.Document.GetElementsByTagName("A");
foreach (HtmlElement link in links) // this ex is given another SO post
{
if (link.InnerText.Equals("My Assigned"))
link.InvokeMember("Click");
}
Can any body suggest how to do it ??
Solved :
I changed to HtmlElementCollection links = webBrowser.Document.GetElementsByTagName("A"); to HtmlElementCollection links = webBrowser1.Document.Links and used
if (link.InnerText.Contains("My Assigned"))
{
link.InvokeMember("Click");
}
. any one who better solution?
InnerText might be null so build in a safeguard, to check for null:
if ((link.InnerText != null) && (link.InnerText.Equals("My Assigned")) )
link.InvokeMember("Click");
Actually, I would get rid of HTMLAgility pack (its pretty bad) and just go/loop through it yourself. Also, don't use innerText, because based on your examples, there doesn't seem to be an innertext in at least one of the links. Use the .href attribute and check for the .csv extension.
link.href.EndsWith(".csv")
And if there are more than one .cvs on each page, look for some url string or innertext property to refine it.
Also, the reason why your .GetElementsByTagName("A") was not working was because TagName refers to the name attribute of any particular TAG. So, you were saying, Get all TAG's with the TagType name="A"... does that make sense? I think there is a .GetElementsByTag[Type] or something like that which you can use to base it on the tag type and not the name attribute of a TAG.
Also, how are you downloading the .csv file? Is a "download dialog" box coming up or are you just showing people in the webbrowser control? (curious how you've handled that part).

Place Image from DLL onto a web page

I'm so stuck on something i thought would be easy.
I have a DLL that returns an Image object.
I just cant figure out how to display that image on a webpage.
I've tried a few ways, and google a million different variations.
Is it not possible to just bind an Image object to an element on the page like an HtmlImage or a simple img?
Or do i need to convert the Image to a Stream? or a Bitmap? I'm really stuck!
Any help appreciated.....
V
With Asp.Net WebForm, the easiest way is to create a custom ashx file.
In Visual Studio, create a new Custom Handler (I'm not sure of the name of the template in Visual Studio). This will create a .ashx file.
In the code of this handler, write something like (does not have VS under the hand to test the syntax) :
public void ProcessRequest(System.Web.HttpContext context)
{
byte[] raw;
using(var ms = new MemoryStream()){
Image myImage = GetFromDll();
myImage.Save(ms, ImageFormat.Png);
raw=ms.ToArray();
}
context.Response.ContentType = "image/png";
context.Response.BinaryWrite(raw);
}
Then, in your browser, navigate to http://yourserver/app/yourhandler.ashx.
You can if you want add url parameter, and get it from the Request.QueryString collection
It's not as simple as binding. On the client side images are retrieved from the web server as a separate GET request, which means you have to have a URL that resolves to an image. The other option, as Asif suggested, is embedding your image in the HTML as a Base64 string, which is bad practice for shared images (see Steve B's comment).
You either have to provide an URL (route that returns the image file in MVC, or a custom page with proper content type and Response.Write in WebForms), or embed in html.
EDIT:
There is also a third option involving custom HTTP handlers. These have the advantage of bypassing the app framework and serving the content almost directly off the web server, see MSDN.
Convert your image to base64 string and then set it in the <img/> tag.
<img/> can show the image in base64 string.
Alternatively you can save the image and use the path in the <img/>.

Categories