【问题标题】:Taking screenshot using javascript for chrome extensions使用 javascript 为 chrome 扩展截取屏幕截图
【发布时间】:2022-01-16 08:42:56
【问题描述】:

我搜索了很多关于使用 JS 拍照的信息,但似乎没有一个有用。有人说使用 activeX 控件,这不适合我的情况。我希望用JS拍照并上传到服务器。

【问题讨论】:

    标签: javascript google-chrome-extension


    【解决方案1】:

    由于您在 Chrome 扩展程序中使用它,Tab API 有一个名为 captureVisibleTab 的方法,它允许捕获指定窗口中当前选定选项卡的可见区域。

    要使用它,您只需将“标签”添加到您的 permissions 清单中。从您的背景页面或弹出窗口(或任何其他扩展页面)中,您只需像这样调用该方法:

    chrome.tabs.captureVisibleTab(null, {}, function (image) {
       // You can add that image HTML5 canvas, or Element.
    });
    

    您可以通过添加 {quality: 50} 来控制属性并更改格式,所有这些都在上述文档中进行了描述。

    HTML5 的美妙之处,您可以使用 HTML5 Canvas 更改该图像,您可以非常轻松地操作、转换、修改、剪辑任何您想要的东西!

    希望这就是您想要的!新年快乐!

    【讨论】:

    • 我已经添加了选项卡的权限,但是当我使用警报“图像”时,我得到“未定义”。你知道为什么吗?
    • 有什么方法可以截取不可见的标签页?
    • 截图需要权限
    • Chrome 59 现已提供整页屏幕截图。您知道是否可以通过 Extensions API 访问此功能? developers.google.com/web/updates/2017/04/…
    • @skibulk 我认为在 59 中,该功能是通过向下滚动并将可见的屏幕区域拼接在一起来完成的。但是,是的,为我们完成它会非常好:) 而不是必须进行图像处理......
    【解决方案2】:

    我不确定在给出原始答案时这是否可用,但谷歌现在有一个可用的示例显示如何截取屏幕截图:

    http://developer.chrome.com/extensions/samples.html

    在此页面上搜索“测试屏幕截图扩展”。

    更新:这是使用 desktopCapture API 的新示例:

    https://github.com/GoogleChrome/chrome-extensions-samples/tree/main/apps/samples/desktop-capture

    【讨论】:

    • 链接失效
    • @DaraJava 找到了更新的示例。谢谢。
    【解决方案3】:

    如果您正在寻找工作示例,我已经创建了带有扩展名的 repo,它截取了整个网页的屏幕截图。看这里:https://github.com/marcinwieprzkowicz/take-screenshot

    【讨论】:

    【解决方案4】:

    这是另一种对我有用的方法。
    要求如下:
    (a) 在 chrome 扩展中捕获屏幕截图
    (b) 截图必须有透明背景
    (c) 必须将屏幕截图传达给不同的进程(通过 HTTP)

    在本节中,我将介绍代码片段寻址要求 (b)
    有用的参考资料是:
    chrome extensions debugger api
    chrome devtools protocol debugger domain
    你可能想从最后一个函数attachToDebugger开始阅读代码

    function captureScreenshot(tabId) {
    
        logMsg(`{page}: captureScreenshot: status=aboutTo, tabId=${tabId}`);
    
        chrome.debugger.sendCommand(
            {tabId:tabId},
            "Page.captureScreenshot", 
            {format: "png", fromSurface: true},
            response => {
                if(chrome.runtime.lastError) {
                    logMsg(`{back}: captureScreenshot: status=failed, tabId=${tabId}`);
                }
                else {
                    var dataType = typeof(response.data);
                    logMsg(`{back}: captureScreenshot: status=success, tabId=${tabId}, dataType=${dataType}`);
                    saveScreenshotRemotely(response.data);
                }
            });
    
        logMsg(`{page}: captureScreenshot: status=commandSent, tabId=${tabId}`);
    }
    
    //---------------------------------------------------------------------------
    
    function setColorlessBackground(tabId) {
    
        logMsg(`{back}: setColorlessBackground: status=aboutTo, tabId=${tabId}`);
    
        chrome.debugger.sendCommand(
            {tabId:tabId}, 
            "Emulation.setDefaultBackgroundColorOverride",
            {'color': {'r': 0, 'g': 0, 'b': 0, 'a': 0}},
            function () {
                logMsg(`{back}: setColorlessBackground: status=enabled, tabId=${tabId}`);
                captureScreenshot(tabId);
            });
    
        logMsg(`{back}: setColorlessBackground: status=commandSent, tabId=${tabId}`);
    }
    
    //---------------------------------------------------------------------------
    
    function enableDTPage(tabId) {
    
        logMsg(`{back}: enableDTPage: status=aboutTo, tabId=${tabId}`);
    
        chrome.debugger.sendCommand(
            {tabId:tabId}, 
            "Page.enable", 
            {}, 
            function () {
                logMsg(`{back}: enableDTPage: status=enabled, tabId=${tabId}`);
                setColorlessBackground(tabId);
                /*
                 * you can comment 
                 * setColorlessBackground(tabId);
                 * and invoke 
                 * captureScreenshot(tabId);
                 * directly if you are not interested in having a 
                 * transparent background
                 */
            });
    
        logMsg(`{back}: enableDTPage: status=commandSent, tabId=${tabId}`);
    }
    
    //---------------------------------------------------------------------------
    
    function attachToDebugger(tabId) {
        chrome.debugger.attach(
            {tabId:tabId}, 
            g_devtools_protocol_version,
            () => {
                if (chrome.runtime.lastError) {
                    alert(chrome.runtime.lastError.message);
                    logMsg(`{back}: debugger attach failed: error=${chrome.runtime.lastError.message}`);
                }
                else {
                    logMsg(`{back}: debugger attach success: tabId=${tabId}`);
                    enableDTPage(tabId);
                }
            });
    }
    

    【讨论】:

    • 这比 captureVisibleTab API 更好,前提是你的扩展可以附加调试器。您还可以使用 --silent-debugger-extension-api 启动 Chrome,以避免显示扩展程序已开始调试的信息栏。
    【解决方案5】:

    如果您在企业内部,您的 IT 可能会将政策 DisableScreenshots 设置为 true。 您可以通过进入 chrome://policy 并搜索此密钥来检查它。

    【讨论】: