~ubuntu-branches/ubuntu/precise/koffice/precise

« back to all changes in this revision

Viewing changes to krita/plugins/filters/blur/kis_lens_blur_filter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2010-10-27 17:52:57 UTC
  • mfrom: (0.12.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20101027175257-s04zqqk5bs8ckm9o
Tags: 1:2.2.83-0ubuntu1
* Merge with Debian git remaining changes:
 - Add build-deps on librcps-dev, opengtl-dev, libqtgtl-dev, freetds-dev,
   create-resources, libspnav-dev
 - Remove needless build-dep on libwv2-dev
 - koffice-libs recommends create-resources
 - krita recommends pstoedit
 - Keep our patches
* New upstream release 2.3 beta 3
  - Remove debian/patches fixed by upstream
  - Update install files

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of Krita
 
3
 *
 
4
 * Copyright (c) 2010 Edward Apap <schumifer@hotmail.com>
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 2 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, write to the Free Software
 
18
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
19
 */
 
20
 
 
21
 
 
22
#include "kis_lens_blur_filter.h"
 
23
#include "kis_wdg_lens_blur.h"
 
24
 
 
25
#include <kcombobox.h>
 
26
#include <knuminput.h>
 
27
 
 
28
#include <KoCompositeOp.h>
 
29
 
 
30
#include <kis_convolution_kernel.h>
 
31
#include <kis_convolution_painter.h>
 
32
#include <kis_iterators_pixel.h>
 
33
 
 
34
#include "ui_wdg_lens_blur.h"
 
35
 
 
36
#include <filter/kis_filter_configuration.h>
 
37
#include <kis_selection.h>
 
38
#include <kis_paint_device.h>
 
39
#include <kis_processing_information.h>
 
40
 
 
41
#include <QPainter>
 
42
 
 
43
#include <math.h>
 
44
 
 
45
 
 
46
KisLensBlurFilter::KisLensBlurFilter() : KisFilter(id(), categoryBlur(), i18n("&Lens Blur..."))
 
47
{
 
48
    setSupportsPainting(true);
 
49
    setSupportsPreview(true);
 
50
    setSupportsIncrementalPainting(true);
 
51
    setSupportsAdjustmentLayers(true);
 
52
    setColorSpaceIndependence(FULLY_INDEPENDENT);
 
53
}
 
54
 
 
55
KisConfigWidget * KisLensBlurFilter::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP, const KisImageWSP image) const
 
56
{
 
57
    Q_UNUSED(image)
 
58
    return new KisWdgLensBlur(parent);
 
59
}
 
60
 
 
61
KisFilterConfiguration* KisLensBlurFilter::factoryConfiguration(const KisPaintDeviceSP) const
 
62
{
 
63
    KisFilterConfiguration* config = new KisFilterConfiguration(id().id(), 1);
 
64
    config->setProperty("irisShape", "Pentagon (5)");
 
65
    config->setProperty("irisRadius", 5);
 
66
    config->setProperty("irisRotation", 0);
 
67
 
 
68
    return config;
 
69
}
 
70
 
 
71
void KisLensBlurFilter::process(KisConstProcessingInformation srcInfo,
 
72
                            KisProcessingInformation dstInfo,
 
73
                            const QSize& size,
 
74
                            const KisFilterConfiguration* config,
 
75
                            KoUpdater* progressUpdater
 
76
                           ) const
 
77
{
 
78
    const KisPaintDeviceSP src = srcInfo.paintDevice();
 
79
    KisPaintDeviceSP dst = dstInfo.paintDevice();
 
80
    QPoint dstTopLeft = dstInfo.topLeft();
 
81
    QPoint srcTopLeft = srcInfo.topLeft();
 
82
 
 
83
    Q_ASSERT(src != 0);
 
84
    Q_ASSERT(dst != 0);
 
85
 
 
86
    if (!config) config = new KisFilterConfiguration(id().id(), 1);
 
87
 
 
88
    QVariant value;
 
89
    config->getProperty("irisShape", value);
 
90
    QString irisShape = value.toString();
 
91
    config->getProperty("irisRadius", value);
 
92
    uint irisRadius = value.toUInt();
 
93
    config->getProperty("irisRotation", value);
 
94
    uint irisRotation = value.toUInt();
 
95
 
 
96
    if (irisRadius < 1)
 
97
        return;
 
98
 
 
99
    QBitArray channelFlags;
 
100
    if (config) {
 
101
        channelFlags = config->channelFlags();
 
102
    } 
 
103
    if (channelFlags.isEmpty() || !config) {
 
104
        channelFlags = QBitArray(src->colorSpace()->channelCount(), true);
 
105
    }
 
106
    
 
107
    QPolygonF irisShapePoly;
 
108
 
 
109
    int sides = 1;
 
110
    qreal angle = 0;
 
111
 
 
112
    if (irisShape == "Triangle") sides = 3;
 
113
    else if (irisShape == "Quadrilateral (4)") sides = 4;
 
114
    else if (irisShape == "Pentagon (5)") sides = 5;
 
115
    else if (irisShape == "Hexagon (6)") sides = 6;
 
116
    else if (irisShape == "Heptagon (7)") sides = 7;
 
117
    else if (irisShape == "Octagon (8)") sides = 8;
 
118
    else return;
 
119
 
 
120
    for (int i = 0; i < sides; ++i) {
 
121
        irisShapePoly << QPointF(0.5 * cos(angle), 0.5 * sin(angle));
 
122
        angle += 2 * M_PI / sides;
 
123
    }
 
124
 
 
125
    QTransform transform;
 
126
    transform.rotate(irisRotation);
 
127
    transform.scale(irisRadius * 2, irisRadius * 2);
 
128
 
 
129
    QPolygonF transformedIris;
 
130
    for (int i = 0; i < irisShapePoly.count(); ++i) {
 
131
        transformedIris << irisShapePoly[i] * transform;
 
132
    }
 
133
 
 
134
    // find extremes to determine kernel size required
 
135
    qreal minX = 0, maxX = 0, minY = 0, maxY = 0;
 
136
    for (int i = 0; i < transformedIris.count(); ++i) {
 
137
        if (transformedIris[i].x() < minX) minX = transformedIris[i].x();
 
138
        if (transformedIris[i].x() > maxX) maxX = transformedIris[i].x();
 
139
        if (transformedIris[i].y() < minY) minY = transformedIris[i].y();
 
140
        if (transformedIris[i].y() > maxY) maxY = transformedIris[i].y();
 
141
    }
 
142
 
 
143
    int kernelWidth = ceil(maxX) - ceil(minX);
 
144
    int kernelHeight = ceil(maxY) - ceil(minY);
 
145
 
 
146
    QImage kernelRepresentation(kernelWidth, kernelHeight, QImage::Format_RGB32);
 
147
    kernelRepresentation.fill(0);
 
148
 
 
149
    QPainter imagePainter(&kernelRepresentation);
 
150
    imagePainter.setRenderHint(QPainter::Antialiasing);
 
151
    imagePainter.setBrush(QColor::fromRgb(255, 255, 255));
 
152
 
 
153
    QTransform offsetTransform;
 
154
    offsetTransform.translate(-minX, -minY);
 
155
    imagePainter.setTransform(offsetTransform);
 
156
    imagePainter.drawPolygon(transformedIris, Qt::WindingFill);
 
157
 
 
158
    // construct kernel from image
 
159
    Matrix<qreal, Dynamic, Dynamic> irisKernel(kernelHeight, kernelWidth);
 
160
    for (int j = 0; j < kernelHeight; ++j) {
 
161
        for (int i = 0; i < kernelWidth; ++i) {
 
162
            irisKernel(j, i) = qRed(kernelRepresentation.pixel(i, j));
 
163
        }
 
164
    }
 
165
 
 
166
    // apply convolution
 
167
    KisConvolutionPainter painter(dst, dstInfo.selection());
 
168
    painter.setChannelFlags(channelFlags);
 
169
    painter.setProgress(progressUpdater);
 
170
 
 
171
    KisConvolutionKernelSP kernel = KisConvolutionKernel::fromMatrix(irisKernel, 0, irisKernel.sum());
 
172
    painter.applyMatrix(kernel, src, srcTopLeft, dstTopLeft, size, BORDER_REPEAT);
 
173
}