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.
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!