标签:qml qt quick 图像混合 graphical effects
Qt Quick提供了通过改变一个 Item 的颜色来产生各种各样效果的元素。有下面几种:
因为有多种颜色效果,每种又支持不同的、可调整的属性,所以在设计示例时和上次讲的 Blend 又有不同。
博客之星评选,点击投我一票,谢谢。投过了也可以点哦,每天都可以投投一票。
我设计了一个示例: ColorExample.qml 。这个 QML 文档与 BlendExample 一样,都被加入到 GraphicalEffects 项目中的 qrc 中。使用到的图片 bug.jpg 和 butterfly.png 也在 qrc 中。
看一下效果:
图 1 颜色效果示例
如图 1 所示,界面分三个部分,与 Blend 示例类似。上方是原始图片,下方左侧是颜色效果类型列表,下方右侧用来展示某个效果类型的用法和效果。
如你所见,右下方白色背景那部分,会根据 Color Effects 列表中的条目而变化,是动态加载的,在代码中通过 Loader 来动态加载某个效果对应的 qml 文档。
到现在为止,我们的示例中的 qml 文档,已经分了三层:
颜色效果种类太多了,我真想说:看 Qt 帮助去吧。可这太不负责任了不是,所以我决定还是挑一个来讲一下,就挑 BrightnessContrast 吧,它不是最简单的,也不是复杂的。
与 Blend 类似的是,各种颜色效果元素操作 source 的结果是产生一个新的 Item 。不同的是,颜色效果元素只有一个 source 属性,没有 foregroundSource 属性,即:它只需要一个源 Item ,通过改变源 Item 的颜色来产生图形效果。
看名字就知道了,这个元素是改变亮度和对比度的,所以它有两个属性, brightness 和 contrast ,分别改变源 Item (通过 source 属性指定)的亮度和对比度;它们的取值范围都是 -1.0 ~ 1.0 ,默认值都是 0.0 。
另外还有一个 cached 属性,介绍 Blend 时已经提到了,设置为 true 可以缓存处理后的图像,提高渲染速度。默认值为 false 。
每一个颜色效果的示例我都在一个单独的 qml 文档中实现,当用户点击图 1 中的颜色效果列表时,通过改变 Loader 的 source 属性来动态加载对应的 QML 文档。 BrightnessContrast 对应的 qml 文档是 BrightnessContrastEx.qml ,内容如下:
import QtQuick 2.2 import QtGraphicalEffects 1.0 import QtQuick.Controls 1.2 Rectangle { anchors.fill: parent; Image { id: opImage; x: 4; y: 4; width: 250; height: 250; source: "bug.jpg"; sourceSize: Qt.size(250, 250); smooth: true; visible: false; } BrightnessContrast { anchors.fill: opImage; source: opImage; brightness: bslider.value; contrast: cslider.value; } Text { id: blabel; text: "Brightness:"; anchors.left: opImage.left; anchors.top: opImage.bottom; anchors.margins: 4; } Slider { id: bslider; anchors.left: blabel.right; anchors.leftMargin: 8; anchors.verticalCenter: blabel.verticalCenter; width: 200; height: 40; minimumValue: -1.0; value: 0.5; } Text { id: clabel; text: "Contrast:"; anchors.left: blabel.left; anchors.top: bslider.bottom; anchors.topMargin: 4; } Slider { id: cslider; anchors.left: bslider.left; anchors.verticalCenter: clabel.verticalCenter; width: 200; height: 40; minimumValue: -1.0; value: 0.5; } }
当我们拖动滑块时, BrightnessContrast 对象的相应属性值就会随着滑块的拖动而改变,我们看到的目标 Item 的效果就跟着变了。
这个是颜色效果里最复杂的了……说了这个就不说了,其它的就看帮助吧。先看下效果:
图2 LevelAdjust 效果
LevelAdjust 元素可以根据 gamma 曲线调整源 Item 的 R 、 G 、 B 三个通道的颜色值,这个比 GammaAdjust 更彪悍。 可以用 Qt.vector3d() 构造一个 3d 向量赋值给 LevelAdjust 的 gamma 属性,图 2 就是这么干的。如你所见,我把 3D 向量的构造代码显示出来了,你点击它,可以调出一个对话框,对话框上有三个 Slider 。如下图所示:
图 3 GammaVector对话框
这个对话框我定义在 GammaVector.qml 文档中,代码如下:
import QtQuick 2.2 import QtQuick.Dialogs 1.2 import QtQuick.Controls 1.2 Rectangle { id: gammaCreator; width: 250; height: 30; property vector3d gamma: Qt.vector3d(1.0, 1.0, 1.0); signal selected(); color: "lightgray"; border.width: 1; border.color: "darkgray"; Text { id: gammaLabel; anchors.centerIn: parent; text: "Qt.vector3d(1.0, 1.0, 1.0)"; color: "darkblue"; } MouseArea { anchors.fill: parent; onClicked: vectorDlg.visible = true; } Dialog { id: vectorDlg; visible: false; width: 300; height: 200; standardButtons: StandardButton.Ok | StandardButton.Cancel; onAccepted: { gammaCreator.gamma = Qt.vector3d(one.value, two.value, three.value); gammaLabel.text = "Qt.vector3d(%1,%2,%3)".arg(one.value.toFixed(1)).arg(two.value.toFixed(1)).arg(three.value.toFixed(1)); gammaCreator.selected(); } Grid { x: 0; y: 4; width: 300; height: 120; verticalItemAlignment: Grid.AlignVCenter; columns: 3; Text { text: "0.0"; width: 50; horizontalAlignment: Text.AlignRight; } Slider { id: one; minimumValue: 0.0; maximumValue: 10.0; value: 1.0; width: 180; height: 30; } Text { text: "10.0"; width: 50; } Text { text: "0.0"; width: 50; horizontalAlignment: Text.AlignRight; } Slider { id: two; minimumValue: 0.0; maximumValue: 10.0; value: 1.0; width: 180; height: 30; } Text { text: "10.0"; width: 50; } Text { text: "0.0"; width: 50; horizontalAlignment: Text.AlignRight; } Slider { id: three; minimumValue: 0.0; maximumValue: 10.0; value: 1.0; width: 180; height: 30; } Text { text: "10.0"; width: 50; } } } }
minimumInput 和 maximumInput 这两个属性是一对。 minimumInput 设定像素的黑色阈值,当一个像素的值小于 minimumInput 指定的颜色值时,就会被替换为黑色。maximumInput 设定像素的白色阈值,当一个像素的值大于 maximumInput 指定的颜色值时,就会被替换为白色。PhotoShop 里有这样的功能,可以批量把一个图片内低于给定值的像素修改为黑色。
minimumOutput 和 maximumOutput 是一对。minimumOutput 定义每个颜色通道的最小输出水平,这个值增加会让黑暗的区域变量,同时会降低对比度。maximumOutput 定义每个颜色通道的最大输出水平,减小这个值会让明亮的区域变暗,同时会降低对比度。
minimumInput 、 maximumInput 、 minimumOutput 、 maximumOutput 四个属性的取值范围都是 "#00000000" 到 "#FFFFFFFF"。
为了让用户能够选择一个颜色,我定义了一个单独的组件(ColorPicker.qml),如果你在图2中看到的那样,点击可以弹出一个颜色选择对话框,选择后这个组件就会改变自己的颜色,并将新颜色的值以字符串("#AARRGGBB")的形式显示出来。用起来还比较方便。
好了, LevelAdjust 介绍完了,我们看一下 LevelAdjustEx.qml 吧:
import QtQuick 2.2 import QtGraphicalEffects 1.0 import QtQuick.Controls 1.2 Rectangle { anchors.fill: parent; Image { id: opImage; x: 4; y: 4; width: 220; height: 220; source: "butterfly.png"; sourceSize: Qt.size(220, 220); smooth: true; visible: false; } LevelAdjust { id: level; anchors.fill: opImage; source: opImage; minimumInput: minInput.color; maximumInput: maxInput.color; minimumOutput: minOutput.color; maximumOutput: maxOutput.color; } GammaVector { id: gammaSelector; anchors.left: opImage.left; anchors.top: opImage.bottom; anchors.topMargin: 4; onSelected: level.gamma = gammaSelector.gamma; } Grid { anchors.top: gammaSelector.bottom; anchors.topMargin: 4; anchors.left: gammaSelector.left; columns: 4; rowSpacing: 4; columnSpacing: 2; verticalItemAlignment: Grid.AlignVCenter; Text { text: "minimumInput:"; } ColorPicker { id: minInput; width: 90; height: 28; color: "#00000000"; } Text { text: "maximumInput:"; } ColorPicker { id: maxInput; width: 90; height: 28; color: "#ffffffff"; } Text { text: "minimumOutput:"; } ColorPicker { id: minOutput; width: 90; height: 28; color: "#00000000"; } Text { text: "maximumOutput:"; } ColorPicker { id: maxOutput; width: 90; height: 28; color: "#ffffffff"; } } }
-------------------------
图 1 中列出的颜色效果元素,限于篇幅,就不一一介绍了,问道 Qt 帮助吧。
博客之星评选,点击投我一票,谢谢。投过了也可以点哦,每天都可以投投一票。
--------
回顾一下我的Qt Quick系列文章:
标签:qml qt quick 图像混合 graphical effects
原文地址:http://blog.csdn.net/foruok/article/details/42637849