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