窗口截图接口

snapshot(callback: AsyncCallback<image.PixelMap>): void

获取窗口截图,使用Promise异步回调。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.WindowManager.WindowManager.Core

返回值:

img

示例:

import { BusinessError } from '@kit.BasicServicesKit';
import { image } from '@kit.ImageKit';

let promise = windowClass.snapshot();
promise.then((pixelMap: image.PixelMap) => {
  console.info('Succeeded in snapshotting window. Pixel bytes number: ' + pixelMap.getPixelBytesNumber());
  pixelMap.release(); // PixelMap使用完后及时释放内存
}).catch((err: BusinessError) => {
  console.error(`Failed to snapshot window. Cause code: ${err.code}, message: ${err.message}`);
});

说明:目前使用 laphone 和 rk3568 测试该接口,性能如下

img

应用demo代码截图

img

调试日志截图

img

调用 RS 接口如下

napi_value JsWindow::OnSnapshot(napi_env env, napi_callback_info info)
{
    // 获取窗口对象的弱引用
    wptr<Window> weakToken(windowToken_);
    // 定义异步任务完成时的回调函数
    NapiAsyncTask::CompleteCallback complete =
        [weakToken](napi_env env, NapiAsyncTask& task, int32_t status) {
            // 通过弱引用获取窗口对象,如果窗口对象已经销毁则拒绝任务并返回错误状态
            auto weakWindow = weakToken.promote();
            if (weakWindow == nullptr) {
                WLOGFE("window is nullptr");
                task.Reject(env, CreateJsError(env,
                    static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
                return;
            }

            // 调用窗口对象的截图方法,获取像素图对象
            std::shared_ptr<Media::PixelMap> pixelMap = weakWindow->Snapshot();
            // 如果获取的像素图对象为空,则拒绝任务并返回错误状态
            if (pixelMap == nullptr) {
                task.Reject(env, CreateJsError(env,
                    static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
                WLOGFE("window snapshot get pixelmap is null");
                return;
            }


            // 将像素图对象转换为 JavaScript 可用的对象
            auto nativePixelMap = Media::PixelMapNapi::CreatePixelMap(env, pixelMap);
            // 如果转换失败,则记录错误信息
            if (nativePixelMap == nullptr) {
                WLOGFE("window snapshot get nativePixelMap is null");
            }
            // 解析任务并返回结果
            task.Resolve(env, nativePixelMap);
            // 记录截图操作的日志信息
            WLOGFE("Window [%{public}u, %{public}s] OnSnapshot, WxH=%{public}dx%{public}d",
                weakWindow->GetWindowId(), weakWindow->GetWindowName().c_str(),
                pixelMap->GetWidth(), pixelMap->GetHeight());
        };

    // 获取回调函数的参数信息
    size_t argc = 4;
    napi_value argv[4] = {nullptr};
    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
    napi_value lastParam = (argc == 0) ? nullptr :
        ((argv[0] != nullptr && GetType(env, argv[0]) == napi_function) ? argv[0] : nullptr);
    napi_value result = nullptr;

    // 调度异步任务,并传递最后一个参数以及完成回调函数
    NapiAsyncTask::Schedule("JsWindow::OnSnapshot",
        env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));

    // 返回结果对象
    return result;
}

std::shared_ptr<Media::PixelMap> WindowImpl::Snapshot()
{
    std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
    auto isSucceeded = RSInterfaces::GetInstance().TakeSurfaceCapture(surfaceNode_, callback);
    std::shared_ptr<Media::PixelMap> pixelMap;
    if (isSucceeded) {
        pixelMap = callback->GetResult(2000); // wait for <= 2000ms
    } else {
        pixelMap = SingletonContainer::Get<WindowAdapter>().GetSnapshot(property_->GetWindowId());
    }
    if (pixelMap != nullptr) {
        WLOGFD("WMS-Client Save WxH = %{public}dx%{public}d", pixelMap->GetWidth(), pixelMap->GetHeight());
    } else {
        WLOGFE("Failed to get pixelmap, return nullptr!");
    }
    return pixelMap;
}
Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐