Как я могу сохранить изображение с примененной маской непрозрачности?

#qt #qml #qtquick2 #qt-quick #qtquickcontrols

Вопрос:

Я работаю над проектом, в котором я хочу сохранить уменьшенное изображение визуализированного экрана в точности таким, как оно отображается, в том числе с помощью приложения an 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) )   }  } }   

Ответ №1:

Похоже, это проблема с областью видимости, когда вы захватываете изображение на уровне, на котором маска не применяется. Используйте grabToImage() функцию вашего frame Rectangle родителя. Например, я добавил идентификатор к этому родителю, а вместо этого вызвал его и получил правильный вывод:

 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 и вместо этого вызвав grabToImage() функцию на OpacityMask вместо этого. Однако приведенное выше решение было намного проще.

Комментарии:

1. Прелестно! Приятно видеть, что я был не так уж далек от истины.