special effects with qt graphics view
DESCRIPTION
Graphics View becomes one of the prominent features of Qt these days, it also serves as the backbone for next-generation user-interface developments. This talk highlights several tips and tricks which you can employ to beautify your Graphics View-based application, in order to have much more exciting and interesting user interactions. In addition, a new addition in Qt 4.6, namely the graphics effect feature, will be introduced and demonstrated. Presentation by Ariya Hidayat held during Qt Developer Days 2009. http://qt.nokia.com/developer/learning/elearningTRANSCRIPT
Special F/X with Graphics ViewAriya Hidayat 09/25/09
About Myself
2
Open-source Developer
Ph.D in EE
Agenda
Four Dot Five– What you can do already
Four Dot Six– What you can (ab)use soon
3
Goals
Provoke ideas!
Incite passion!
Engage creativity!
4
A Word of Caution
With great power must come great responsibility.
5
Spread the Love
All examples are available from...
6
labs.qt.nokia.com
bit.ly/graphicsdojo
Qt 4.5
7
Gradients
Transformation
Animation, Kinetic Scrolling
Composition Modes
8
Linear Gradient
9
Radial Gradient
10
Gradients: Quick Recipe
11
Applies to: QAbstractGraphicsShapeItem
QGraphicsEllipseItem, QGraphicsPathItem, QGraphicsPolygonItem, QGraphicsRectItem
or your own subclass(es).
Classes to use:– QLinearGradient– QRadialGradient– QConicalGradient
Linear Gradient: The Code
12
QPoint start(0, 0);QPoint end(0, 20);
QLinearGradient g(start, end);g.setColorAt(0, Qt::white);g.setColorAt(1, Qt::black);
item->setBrush(g);
Radial Gradient: The Code
13
QRadialGradient gr(100, 100, 100, 60, 60);gr.setColorAt(0.0, QColor(255, 255, 255, 191));gr.setColorAt(0.2, QColor(255, 255, 127, 191));gr.setColorAt(0.9, QColor(150, 150, 200, 63));p.setBrush(gr);p.drawEllipse(0, 0, 200, 200);
Shadow with Gradients
14
magnifier
Shadow: The Code
15
QRadialGradient g;g.setCenter(radius, radius);g.setFocalPoint(radius, radius);g.setRadius(radius);g.setColorAt(1.0, QColor(255, 255, 255, 0));g.setColorAt(0.5, QColor(128, 128, 128, 255));
QPainter mask(&maskPixmap);mask.setCompositionMode (QPainter::CompositionMode_Source);mask.setBrush(g);mask.drawRect(maskPixmap.rect());mask.setBrush(QColor(Qt::transparent));mask.drawEllipse(g.center(), radius-15, radius-15);mask.end();
Translucent Reflection
16
Flip Vertically
17
QImage::mirrored()
More Natural Look
18
Linear gradient, on the alpha channel
Reflection: The Code
19
QPoint start(0, 0);QPoint end(0, img.height());QLinearGradient gradient(start, end);gradient.setColorAt(0.5, Qt::black);gradient.setColorAt(0, Qt::white);
QImage mask = img;QPainter painter(&mask);painter.fillRect(img.rect(), gradient);painter.end();
QImage reflection = img.mirrored();reflection.setAlphaChannel(mask);
Opacity
20
QPainter::setOpacity(...)
Transformation
21
Scaling Rotation Perspective
Rotation
22
transform.rotate(30, Qt::ZAxis)
Perspective Transformation: The Recipe
23
transform.rotate(60, Qt::YAxis)
transform.rotate(60, Qt::XAxis)
Reflection & Transformation
24
Timeline-based Animation
25
acceleration
deacceleration
Linear Motion vs Non-linear Motion
2626
EaseInOutLinear
acceleration
deacceleration
Flick List (or Kinetic Scrolling)
27
Using FlickCharm
28
QGraphicsView canvas;
FlickCharm charm;charm.activateOn(&canvas);
Flick Charm & Event Filtering
29
Steady
Pressed
Manual Scroll
Auto Scroll
Stop
Mouse release
Mouse move
Mouse release
Mouse press
Mousemove
Timer tick
Mouse press
Parallax Effect
30
Composition Modes
31
Colorize (or Tint Effect)
32
Grayscale Conversion
33
int pixels = img.width() * img.height();unsigned int *data = (unsigned int *)img.bits();for (int i = 0; i < pixels; ++i) { int val = qGray(data[i]); data[i] = qRgb(val, val, val);}
Overlay with Color
34
QPainter painter(&resultImage);painter.drawImage(0, 0, grayscaled(image));painter.setCompositionMode (QPainter::CompositionMode_Overlay);painter.fillRect(resultImage.rect(), color);painter.end();
Glow Effect
35
Night Mode
36
Night Mode with Color Inversion
37
QPainter p(this);p.setCompositionMode (QPainter::CompositionMode_Difference);p.fillRect(event->rect(), Qt::white);p.end();
red = 255 – red
green = 255 – green
blue = 255 - blue
A Friendly Advice: Fast Prototyping
38
– avoid long edit-compile-debug cycle– use JavaScript, e.g. with Qt Script– use Python, e.g. with PyQt or PySide– use <insert your favorite dynamic language>
Qt 4.6
39
Animation Framework
State Machine
Graphics Effects
40
Animation Framework
41
What People Want
42
– (soft) drop shadow– blur– colorize– some other random stuff
Graphics F/X
43
QGraphicsEffect
QGraphicsColorizeEffect
QGraphicsGrayscaleEffect
QGraphicsPixelizeEffect
QGraphicsBlurEffect
QGraphicsDropShadowEffect
QGraphicsOpacityEffect
Challenges
44
– software vs hardware– good API
Software vs Hardware
45
– software implementation• consistent and reliable• easy to test• cumbersome, (dog)slow
– hardware acceleration• blazing fast• custom effects are easy• silicon/driver dependent
API
One API to rule them all, ...
46
Simple API
47
– Effect is a QObject• might have property, e.g. Color• property change emits a signal• can be animated easily
– Effect applies to QGraphicsItem & QWidget– Custom effect? Subclass QGraphicsEffect
As Simple As...
48
QGraphicsGrayscaleEffect *effect;effect = new QGraphicsGrayscaleEffect;item->setGraphicsEffect(effect);
Effect is applied to the itemand its children!
Grayscale Effect
49
Grayscale Effect with Strength=0.8
50
Colorize Effect
51
Colorize Effect with Strength=0.8
52
Pixelize Effect
53
Blur Effect
54
Drop Shadow Effect
55
Lighting Example
56
Blur Picker Example
57
sharp
blurry
Fade Message Example
58
Something will happen
Scale Effect
59
Scale Effect Implementation
60
void draw(QPainter *painter, QGraphicsEffectSource *source) {
QPixmap pixmap; pixmap = source->pixmap(Qt::DeviceCoordinates);
painter->save(); painter->setBrush(Qt::NoBrush); painter->setPen(Qt::red); painter->drawRect(pixmap.rect());
painter->scale(0.5, 0.5); painter->translate(pixmap.rect().bottomRight()/2); painter->drawPixmap(0, 0, pixmap);
painter->restore();}
Night Mode Effect
61
Night Mode Effect Implementation
62
void draw(QPainter *painter, QGraphicsEffectSource *source) {
QPixmap pixmap; pixmap = source->pixmap(Qt::DeviceCoordinates);
QPainter p(&pixmap); p.setCompositionMode (QPainter::CompositionMode_Difference); p.fillRect(pixmap.rect(), Qt::white); p.end(); painter->drawPixmap(0, 0, pixmap);}
Frame Effect
63
Extending the Bounding Box
64
QRectF boundingRectFor(const QRectF &rect) const { return rect.adjusted(-5, -5, 5, 5);}
item bounding box
“effective” bounding box
Frame Effect Implementation
65
void draw(QPainter *painter, QGraphicsEffectSource *source) {
QPixmap pixmap; pixmap = source->pixmap(Qt::DeviceCoordinates); QRectF bound = boundingRectFor(pixmap.rect());
painter->save(); painter->setPen(Qt::NoPen); painter->setBrush(Qt::green); painter->drawRoundedRect(bound, 15, 15); painter->drawPixmap(0, 0, pixmap); painter->restore();}
Reflection Effect
66
Enlarging the Bounding Box (Again)
67
QRectF boundingRectFor(const QRectF &rect) const { return rect.adjusted(0, 0, 0, rect.height());}
item bounding box
“effective” bounding box
Reflection Effect Implementation
68
void draw(QPainter *painter, QGraphicsEffectSource *source) {
QPixmap pixmap; pixmap = source->pixmap(Qt::DeviceCoordinates);
painter->save(); painter->drawPixmap(0, 0, pixmap); painter->setOpacity(0.2); painter->scale(1, -1); painter->translate(0, -pixmap.height()); painter->drawPixmap(0, 0, pixmap); painter->restore();}
Qt 4.7?
Future?
69
Declarative UI
70
Further Directions
71
– Optimization!– Composite effects– Geometry deformation– Morphing– More physics: force, gravity, ...– Bitmap vs vector
Genie Effect
72
Deformation
73
Underwater Effect
74
Thank You!
75
That's all, folks...
Bleeding-Edge
76
labs.qt.nokia.com
bit.ly/graphicsdojo