1 /******************************************************************************
2 QtAV: Multimedia framework based on Qt and FFmpeg
3 Copyright (C) 2012-2016 Wang Bin <wbsecg1@gmail.com>
4
5 * This file is part of QtAV (from 2013)
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 ******************************************************************************/
21
22 #include "SimpleFilter.h"
23 #include <QWidget>
24 #include <math.h>
25
26 namespace QtAV {
27
SimpleFilter(QObject * parent)28 SimpleFilter::SimpleFilter(QObject *parent):
29 VideoFilter(parent)
30 , mCanRot(true)
31 , mWave(true)
32 {
33 srand(QTime::currentTime().msec());
34 mStartValue = (qreal)(rand()%1000)/qreal(1000.0);
35 mTime.start();
36 startTimer(100);
37 }
38
~SimpleFilter()39 SimpleFilter::~SimpleFilter()
40 {
41 }
42
enableRotate(bool r)43 void SimpleFilter::enableRotate(bool r)
44 {
45 mCanRot = r;
46 }
47
enableWaveEffect(bool w)48 void SimpleFilter::enableWaveEffect(bool w)
49 {
50 mWave = w;
51 }
52
setText(const QString & text)53 void SimpleFilter::setText(const QString &text)
54 {
55 mText = text;
56 }
57
text() const58 QString SimpleFilter::text() const
59 {
60 return mText;
61 }
62
setImage(const QImage & img)63 void SimpleFilter::setImage(const QImage &img)
64 {
65 mImage = img;
66 }
67
prepare()68 void SimpleFilter::prepare()
69 {
70 VideoFilterContext *ctx = static_cast<VideoFilterContext*>(context());
71 if (!mText.isEmpty()) {
72 ctx->font.setPixelSize(32);
73 ctx->font.setBold(true);
74 if (!mCanRot)
75 return;
76 mMat.translate(ctx->rect.center().x(), 0, 0);
77 } else if (!mImage.isNull()) {
78 if (!mCanRot)
79 return;
80 mMat.translate(ctx->rect.x() + mImage.width()/2, 0, 0);
81 }
82 if (mCanRot) {
83 mMat.rotate(mStartValue*360, 0, 1, -0.1);
84 }
85 }
86
timerEvent(QTimerEvent *)87 void SimpleFilter::timerEvent(QTimerEvent *)
88 {
89 if (qobject_cast<QWidget*>(parent()))
90 ((QWidget*)parent())->update();
91 }
92
process(Statistics * statistics,VideoFrame * frame)93 void SimpleFilter::process(Statistics *statistics, VideoFrame *frame)
94 {
95 Q_UNUSED(statistics);
96 Q_UNUSED(frame);
97 if (!isEnabled())
98 return;
99 int t = mTime.elapsed()/100;
100 VideoFilterContext *ctx = static_cast<VideoFilterContext*>(context());
101 if (mCanRot) {
102 mMat.rotate(2, 0, 1, -0.1);
103 ctx->transform = mMat.toTransform();
104 }
105 if (mText.isEmpty()) {
106 if (mImage.isNull())
107 return;
108 if (mCanRot)
109 ctx->drawImage(QPointF(-mImage.width()/2, ctx->rect.y()), mImage, QRectF(0, 0, mImage.width(), mImage.height()));
110 else
111 ctx->drawImage(ctx->rect.topLeft(), mImage, QRectF(0, 0, mImage.width(), mImage.height()));
112 return;
113 }
114 if (mWave) {
115 static int sin_tbl[16] = {
116 0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38
117 };
118
119 QFontMetrics fm(ctx->font);
120 int h = fm.height();
121 int x = ctx->rect.x();
122 int y = ctx->rect.y() + h + fm.descent();
123 for (int i = 0; i < mText.size(); ++i) {
124 int i16 = (t+i) & 15;
125 ctx->pen.setColor(QColor::fromHsv((15-i16)*16, 255, 255));
126 if (mCanRot)
127 ctx->drawPlainText(QPointF(x-fm.width(mText)/2-ctx->rect.x(), y-sin_tbl[i16]*h/400), mText.mid(i, 1));
128 else
129 ctx->drawPlainText(QPointF(x, y-sin_tbl[i16]*h/400), mText.mid(i, 1));
130 x += fm.width(mText[i]);
131 }
132 } else {
133 qreal c = fabs(sin((float)t));
134 c += mStartValue;
135 c /= 2.0;
136 QLinearGradient g(0, 0, 100, 32);
137 g.setSpread(QGradient::ReflectSpread);
138 g.setColorAt(0, QColor::fromHsvF(c, 1, 1, 1));
139 g.setColorAt(1, QColor::fromHsvF(c > 0.5?c-0.5:c+0.5, 1, 1, 1));
140 ctx->pen.setBrush(QBrush(g));
141 ctx->drawRichText(ctx->rect, mText);
142 return;
143 if (mCanRot) {
144 QFontMetrics fm(ctx->font);
145 ctx->drawPlainText(QRectF(-fm.width(mText)/2, ctx->rect.y(), ctx->rect.width(), ctx->rect.height()), Qt::TextWordWrap, mText);
146 } else {
147 ctx->drawPlainText(ctx->rect, Qt::TextWordWrap, mText);
148 }
149 }
150 }
151
152 } //namespace QtAV
153