如何保存应用了 OpacityMask 的图像?

How can I save an image with OpacityMask applied?

我正在做一个项目,我想在其中保存渲染屏幕的缩略图,与显示的完全一样,包括 OpacityMask 的应用程序。问题是无论我做什么,它总是创建缩略图而不应用它。

所以即使屏幕看起来像这样:

创建的图像如下所示:

import QtQuick 2.15
import QtGraphicalEffects 1.12
import QtQuick.Layouts 1.2
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.1

ApplicationWindow {
    id: root
    width: 640
    property bool round: true

    toolBar: ToolBar {
        RowLayout {
            anchors.fill: parent
            anchors.margins: spacing
            CheckBox {
                id: roundCheckBox
                text: "Round"
                Component.onCompleted: checked = round
                onCheckedChanged: round = checked; 
            }
            Item { Layout.fillWidth: true }
        }
    }

    Rectangle {
        height: 640
        width: 640

        Rectangle {
            id: frame
            anchors.fill: parent
            focus: true
            color: "black"
            Image {
                id: background
                source: "background.jpg"
                anchors.fill: parent
            }
            Rectangle {
                anchors.centerIn: parent
                width: parent.width/2
                height: parent.height/2
                color: "red"
            }

            layer.enabled: round
            layer.effect:  OpacityMask {
                anchors.fill: parent
                source: frame
                maskSource: Rectangle {
                    width: frame.width
                    height: frame.height
                    radius: frame.width/2
                }
            }

            Keys.onReturnPressed: frame.grabToImage(
            function(result) {  
                result.saveToFile("example.jpg") 
            }, Qt.size(320, 320) )

        }
    }
}

这似乎是一个范围界定问题,您在未应用蒙版的级别抓取图像。使用 frame Rectangle 父项的 grabToImage() 函数。例如,我向该父级添加了一个 id,而不是调用它,并获得正确的输出:

import QtQuick 2.15
import QtGraphicalEffects 1.12
import QtQuick.Layouts 1.2
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.1

ApplicationWindow {
    id: root
    width: 640
    property bool round: true

    toolBar: ToolBar {
        RowLayout {
            anchors.fill: parent
            anchors.margins: spacing
            CheckBox {
                id: roundCheckBox
                text: "Round"
                Component.onCompleted: checked = round
                onCheckedChanged: round = checked;
            }
            Item { Layout.fillWidth: true }
        }
    }

    Rectangle {
        id: frameParent // set parent ID here
        height: 640
        width: 640

        Rectangle {
            id: frame
            anchors.fill: parent
            focus: true
            color: "black"
            Image {
                id: background
                source: "background.jpg"
                anchors.fill: parent
            }
            Rectangle {
                anchors.centerIn: parent
                width: parent.width/2
                height: parent.height/2
                color: "red"
            }

            layer.enabled: round
            layer.effect:  OpacityMask {
                anchors.fill: parent
                source: frame
                maskSource: Rectangle {
                    width: frame.width
                    height: frame.height
                    radius: frame.width/2
                }
            }

            Keys.onReturnPressed: frameParent.grabToImage( // use parent ID here
            function(result) {
                result.saveToFile("example.jpg")
            }, Qt.size(320, 320) )

        }
    }
}

结果如下example.jpg(使用我自己的随机背景图片):

我还能够通过重新组织您的 layer.effect 而不是调用 OpacityMask 上的 grabToImage() 函数来半成功地使其工作。不过上面的解决方案要简单得多。