标签: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