I want to download image from the page displayed in WebView2 control to local file. There's no API to manipulate page media except getting the page source. Should I use execScriptAsnyc to run script to get the image? No one page was found talking about this in my searching. Hope there's is answer from Overflow visitors.
Asked
Active
Viewed 183 times
0
-
Checked out "https://stackoverflow.com/questions/3749231/download-file-using-javascript-jquery" and use script like: const outsideRes = await fetch("external_url"); const blob = await outsideRes.blob(); const url = window.URL.createObjectURL(blob); const link = document.createElement("a"); link.href = url; link.download = "download"; document.body.appendChild(link); link.click() It works in webview2 devtool console, but no response in "ExecuteScriptAsync()". – xxinduan Jul 11 '23 at 03:23
2 Answers
0
To download an image from a page displayed in the WebView2 control and save it to a local file, you can indeed use ExecuteScriptAsync
method in combination with JavaScript code.
Add the required namespaces:
using Microsoft.Web.WebView2.Core; using System.IO;
Assuming you have a WebView2 control named
webView2
on your WPF form, retrieve its underlyingCoreWebView2
instance:var webView2Control = webView2.EnsureCoreWebView2Async().GetAwaiter().GetResult();
Use
ExecuteScriptAsync
to run JavaScript code that retrieves the image source URL:var script = "document.querySelector('img').src"; // Replace 'img' with the appropriate selector for your image element var imageSourceUrl = await webView2Control.ExecuteScriptAsync(script);
Download the image using the retrieved source URL:
using (var client = new System.Net.WebClient()) { var localFilePath = @"C:\Path\To\Your\Image.jpg"; // Replace with the desired local file path and extension client.DownloadFile(imageSourceUrl, localFilePath); }

Muhammad Owais
- 16
- 1
-
Thanks. Actually, I'm using "WebClient". But it does not work anymore because the web site forbidden this kind of downloading in its "reference" policy. This is why I want to save the image already rendered in the page. – xxinduan Jul 10 '23 at 04:01
0
Here is an example of how i did it by subscribing to event NavigationCompleted handler of my WebView instance:
async void CoreWebView2_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
{
if (!e.IsSuccess)
return;
string html = await webView.ExecuteScriptAsync("document.documentElement.outerHTML");
if (html.Contains("any keyword to detect the page you are interested in"))
{
string img_link = ...; // extraction of the url (in my case the image is not rendered on the page but inside a css.
// So i let webview handles all complexity of html request (cookie etc, site protection etc) by navigating on the url
webView.Source = new Uri(link_from_css); // it triggers NavigationCompleted again! Code will continue on "else" part below
}
// assuming the only links that interests me are ending ".jpg"
else if (webView.Source.AbsolutePath.EndsWith(".jpg"))
{
// No need to specify id of img element here, browser uses only one "img" html element in the page it generates to display the image
// In you case you could call this directly from the code in the if/then part
var imageData = await GetImageBytesAsync(null);
File.WriteAllBytes(@"C:\wherever_you_want\test.jpg", imageData);
}
}
And the helper method:
/// <summary>
/// Get raw data (bytes) about an image in an "img" html element
/// where id is indicated by "elementId".
/// If "elementId" is null, the first "img" element in the page is used
/// </summary>
async Task<byte[]> GetImageBytesAsync(string elementId = null, bool debug = false)
{
var script = @"
function getImageAsBase64(imgElementId)
{
" + (debug ? "debugger;" : "") + @"
let img = document.getElementById(imgElementId);
if (imgElementId == '')
{
var results = document.evaluate('//img', document, null, XPathResult.ANY_TYPE, null);
img = results.iterateNext();
}
let canvas = document.createElement('canvas');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
let ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight);
let base64String = canvas.toDataURL('image/jpeg'); // or 'image/png'
return base64String;
};
getImageAsBase64('" + elementId + "')";
string base64Data = await webView.ExecuteScriptAsync(script);
base64Data = base64Data.Split("base64,")[1].TrimEnd('"');
var result = Convert.FromBase64String(base64Data);
return result;
}
And voila!

Astyan
- 56
- 3