在 CefBrowser 中使用 JavascriptResponse 获取图像(无需下载两次)

Fetching images with JavascriptResponse in CefBrowser (Without downloading twice)

本文关键字:下载 两次 图像 CefBrowser 获取 JavascriptResponse      更新时间:2023-09-26

我正在尝试使用CefSharp(屏幕外)来获取网页中的图像信息。我想避免下载内容两次(我知道我可以从图像标签中提取 src 字符串,然后再次下载图像)。现在,这是我的代码:

using (var browser = new ChromiumWebBrowser("http://example.com"))
{
    //All this does is wait for the entire frame to be loaded.
    await LoadPageAsync(browser);
    var res1 = await browser.EvaluateScriptAsync("document.getElementsByTagName('img')[0].src");
    //res1.Result = the source of the image (A string)
    var res2 = await browser.EvaluateScriptAsync("document.getElementsByTagName('img')[0]");
    //This causes an APPCRASH on CefSharp.BrowserSubprocess.exe
}

按照我的计算方式,CefSharp已经在下载这些图像来渲染网页。我想避免发出第二个请求,从客户端提取这些图像,并直接从客户端提取它们。这可能吗?JavascriptResponse对象的局限性是什么,为什么它会导致 APPCRASH?

一些想法:我想过 base64 对图像进行编码,然后以这种方式将其拉出,但这需要我生成一个画布,每次为我想要的每个图像填充该画布,生成一个 base64 字符串,将其作为字符串带到 c#,然后将其解码回图像。我不知道这会有多有效,但我希望能有更好的解决方案。

这就是我解决它的方式:

result = await browser.EvaluateScriptAsync(@"
;(function() {
    var getDataFromImg = function(img) {
        var canvas = document.createElement('canvas');
        var context = canvas.getContext('2d');
        context.drawImage(img, 0, 0 );
        var dataURL = canvas.toDataURL('image/png');
        return dataURL.replace(/^data:image'/(png|jpg);base64,/, '');
    }
    var images = document.querySelectorAll('.image');
    var finalArray = {};
    for ( var i=0; i<images.length; i++ )
    {
        //I just filled in array. Depending on what you're grabbing, you may want to fill
        //This with objects instead with text to identify each image.
        finalArray.push(getDataFromDiv(images[i]));
    }
    return finalArray;
})()");
    //Helper function for below
    private static string FixBase64ForImage(string image)
    {
        var sbText = new StringBuilder(image, image.Length);
        sbText.Replace("'r'n", string.Empty);
        sbText.Replace(" ", string.Empty);
        return sbText.ToString();
    }
    //In c# convert the data to a memory stream, and then load it from that.
    var bitmapData = Convert.FromBase64String(FixBase64ForImage(image));
    var streamBitmap = new MemoryStream(bitmapData);
    var sourceImage = (Bitmap) Image.FromStream(streamBitmap);

尝试执行这个 JavaScript...

如何从 html 图像中获取 base64 编码数据

CefSharp 应该有 FileReader api。

然后,可以让 EvaluateScriptAsync 调用返回 base64 编码的图像数据。