diff options
| author | Michele Calgaro <michele.calgaro@yahoo.it> | 2024-11-22 18:41:30 +0900 | 
|---|---|---|
| committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2024-11-22 20:55:03 +0900 | 
| commit | 5bed6e4a4c916a97f8fe4d1b07f7eecf4d733b90 (patch) | |
| tree | f89cc49efc9ca1d0e1579ecb079ee7e7088ff8c8 /src/imageplugins/distortionfx | |
| parent | 0bfbf616d9c1fd7abb1bd02732389ab35e5f8771 (diff) | |
| download | digikam-5bed6e4a.tar.gz digikam-5bed6e4a.zip | |
Rename 'digikam' folder to 'src'
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
(cherry picked from commit ee0d99607c14cb63d3ebdb3a970b508949fa8219)
Diffstat (limited to 'src/imageplugins/distortionfx')
11 files changed, 2207 insertions, 0 deletions
| diff --git a/src/imageplugins/distortionfx/Makefile.am b/src/imageplugins/distortionfx/Makefile.am new file mode 100644 index 00000000..fcb7b74a --- /dev/null +++ b/src/imageplugins/distortionfx/Makefile.am @@ -0,0 +1,34 @@ +METASOURCES = AUTO + +INCLUDES = -I$(top_srcdir)/src/utilities/imageeditor/editor \ +	       -I$(top_srcdir)/src/utilities/imageeditor/canvas \ +	       -I$(top_srcdir)/src/libs/histogram \ +	       -I$(top_srcdir)/src/libs/levels \ +	       -I$(top_srcdir)/src/libs/curves \ +	       -I$(top_srcdir)/src/libs/whitebalance \ +	       -I$(top_srcdir)/src/libs/widgets/common \ +	       -I$(top_srcdir)/src/libs/widgets/iccprofiles \ +	       -I$(top_srcdir)/src/libs/widgets/imageplugins \ +	       -I$(top_srcdir)/src/libs/dialogs \ +	       -I$(top_srcdir)/src/libs/dimg \ +	       -I$(top_srcdir)/src/libs/dmetadata \ +	       -I$(top_srcdir)/src/libs/dimg/filters \ +	       -I$(top_srcdir)/src/digikam \ +	       $(LIBKDCRAW_CFLAGS) \ +	       $(all_includes)  + +digikamimageplugin_distortionfx_la_SOURCES = imageplugin_distortionfx.cpp \ +	                                         distortionfxtool.cpp distortionfx.cpp + +digikamimageplugin_distortionfx_la_LIBADD = $(LIB_TDEPARTS) \ +	                                        $(top_builddir)/src/digikam/libdigikam.la + +digikamimageplugin_distortionfx_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -ltdecore -ltdeui $(LIB_TQT) -ltdefx -lkdcraw -ltdeio + +kde_services_DATA = digikamimageplugin_distortionfx.desktop + +kde_module_LTLIBRARIES = digikamimageplugin_distortionfx.la  + +rcdir = $(kde_datadir)/digikam +rc_DATA = digikamimageplugin_distortionfx_ui.rc      +        diff --git a/src/imageplugins/distortionfx/digikamimageplugin_distortionfx.desktop b/src/imageplugins/distortionfx/digikamimageplugin_distortionfx.desktop new file mode 100644 index 00000000..8baca4eb --- /dev/null +++ b/src/imageplugins/distortionfx/digikamimageplugin_distortionfx.desktop @@ -0,0 +1,50 @@ +[Desktop Entry] +Name=ImagePlugin_DistortionFX +Name[bg]=Приставка за снимки - Изкривяващи ефекти +Name[da]=Plugin for forvrængningseffekt +Name[el]=ΠρόσθετοΕικόνας_ΕφέΠαραμόρφωσης +Name[fi]=Vääristymä +Name[hr]=Izobličenje +Name[it]=PluginImmagini_EffettiDiDistorsione +Name[nl]=Afbeeldingsplugin_Vervormingseffect +Name[sr]=Ефекти изобличења +Name[sr@Latn]=Efekti izobličenja +Name[sv]=Insticksprogram för förvrängningseffekt +Name[tr]=ResimEklentisi_Bozma +Name[xx]=xxImagePlugin_DistortionFXxx +Type=Service +X-TDE-ServiceTypes=Digikam/ImagePlugin +Encoding=UTF-8 +Comment=Distortion special effects plugin for digiKam +Comment[bg]=Приставка на digiKam с изкривяващи снимките ефекти +Comment[ca]=Connector pel digiKam d'efectes especials de distorsió +Comment[da]=Digikam plugin for forvrængningsspecialeffekt +Comment[de]=digiKam-Modul zum Erzeugen von speziellen Verzerrungseffekten +Comment[el]=Πρόσθετο ειδικών εφέ παραμόρφωσης για το digiKam +Comment[es]=Plugin para digiKam con efectos de distorsión especiales +Comment[et]=DigiKami spetsiaalsete moonutusefektide plugin +Comment[fa]=وصلۀ جلوههای ویژۀ اعواج برای digiKam +Comment[fi]=Vääristymäerikoistehosteita +Comment[gl]=Un plugin de digiKam para efeitos especiais de distorsión +Comment[hr]=digiKam dodatak za efekt izobličavanja +Comment[is]=Íforrit fyrir digiKam sem afbakar sérstaklega myndir +Comment[it]=Plugin degli effetti speciali di distorsione per digiKam +Comment[ja]=digiKam ゆがめ特殊効果プラグイン +Comment[nds]=digiKam-Moduul för Vertarren-Effekten +Comment[nl]=Digikam-plugin voor vervormingseffect +Comment[pa]=ਡਿਜ਼ੀਕੈਮ ਲਈ ਖਿੰਡਾਉਣ ਖਾਸ ਪਰਭਾਵ ਪਲੱਗਇਨ +Comment[pl]=Wtyczka do programu digiKam oferująca efekty zniekształceń +Comment[pt]=Um 'plugin' do digiKam para efeitos especiais de distorção +Comment[pt_BR]=Plugin de efeito especial de distorção +Comment[ru]=Модуль специальных шумовых эффектов для digiKam +Comment[sk]=digiKam plugin pre špeciálne efekty skreslenia +Comment[sr]=digiKam-ов прикључак за ефекте изобличења +Comment[sr@Latn]=digiKam-ov priključak za efekte izobličenja +Comment[sv]=Digikam insticksprogram för förvrängningsspecialeffekt +Comment[tr]=Bozma etkileri uygulamak için bir digiKam eklentisi +Comment[uk]=Втулок спеціальних ефектів спотворення для digiKam +Comment[vi]=Phần bổ sung hiệu ứng méo mó ảnh cho digiKam +Comment[xx]=xxDistortion special effects plugin for digiKamxx + +X-TDE-Library=digikamimageplugin_distortionfx +author=Caulier Gilles, caulier dot gilles at gmail dot com diff --git a/src/imageplugins/distortionfx/digikamimageplugin_distortionfx_ui.rc b/src/imageplugins/distortionfx/digikamimageplugin_distortionfx_ui.rc new file mode 100644 index 00000000..99b905ad --- /dev/null +++ b/src/imageplugins/distortionfx/digikamimageplugin_distortionfx_ui.rc @@ -0,0 +1,20 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui version="5" name="digikamimageplugin_distortionfx" > + + <MenuBar> + +  <Menu name="Filters" ><text>F&ilters</text> +   <Action name="imageplugin_distortionfx" />  +  </Menu> + + </MenuBar> +  + <ToolBar name="ToolBar" > +  <text>Main Toolbar</text> + </ToolBar> +  + <ActionProperties> +  <Action shortcut="" name="imageplugin_distortionfx" /> + </ActionProperties> + +</kpartgui> diff --git a/src/imageplugins/distortionfx/distortionfx.cpp b/src/imageplugins/distortionfx/distortionfx.cpp new file mode 100644 index 00000000..d17abd4f --- /dev/null +++ b/src/imageplugins/distortionfx/distortionfx.cpp @@ -0,0 +1,869 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date        : 2005-07-18 + * Description : Distortion FX threaded image filter. + * + * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com> + * Copyright (C) 2006-2007 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> + * + * Original Distortion algorithms copyrighted 2004-2005 by  + * Pieter Z. Voloshyn <pieter dot voloshyn at gmail dot com>. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) + * any later version. + *  + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + *  + * ============================================================ */ +  +// Represents 1 +#define ANGLE_RATIO        0.017453292519943295769236907685 + +// C++ includes. + +#include <cmath> +#include <cstdlib> + +// TQt includes. + +#include <tqdatetime.h>  + +// Local includes. + +#include "dimg.h" +#include "dimgimagefilters.h" +#include "distortionfx.h" + +namespace DigikamDistortionFXImagesPlugin +{ + +DistortionFX::DistortionFX(Digikam::DImg *orgImage, TQObject *parent, int effectType, +                           int level, int iteration, bool antialiasing) +            : Digikam::DImgThreadedFilter(orgImage, parent, "DistortionFX") +{  +    m_effectType = effectType; +    m_level      = level; +    m_iteration  = iteration; +    m_antiAlias  = antialiasing; + +    initFilter(); +} + +void DistortionFX::filterImage(void) +{ +    int w = m_orgImage.width(); +    int h = m_orgImage.height(); +    int   l     = m_level; +    int   f     = m_iteration; + +    switch (m_effectType) +    { +        case FishEye: +            fisheye(&m_orgImage, &m_destImage, (double)(l/5.0), m_antiAlias); +            break; + +        case Twirl: +            twirl(&m_orgImage, &m_destImage, l, m_antiAlias); +            break; + +        case CilindricalHor: +            cilindrical(&m_orgImage, &m_destImage, (double)l, true, false, m_antiAlias); +            break; + +        case CilindricalVert: +            cilindrical(&m_orgImage, &m_destImage, (double)l, false, true, m_antiAlias); +            break; + +        case CilindricalHV: +            cilindrical(&m_orgImage, &m_destImage, (double)l, true, true, m_antiAlias); +            break; + +        case Caricature: +            fisheye(&m_orgImage, &m_destImage, (double)(-l/5.0), m_antiAlias); +            break; + +        case MultipleCorners: +            multipleCorners(&m_orgImage, &m_destImage, l, m_antiAlias); +            break; + +        case WavesHorizontal: +            waves(&m_orgImage, &m_destImage, l, f, true, true); +            break; + +        case WavesVertical: +            waves(&m_orgImage, &m_destImage, l, f, true, false); +            break; + +        case BlockWaves1: +            blockWaves(&m_orgImage, &m_destImage, l, f, false); +            break; + +        case BlockWaves2: +            blockWaves(&m_orgImage, &m_destImage, l, f, true); +            break; + +        case CircularWaves1: +            circularWaves(&m_orgImage, &m_destImage, w/2, h/2, (double)l, (double)f, 0.0, false, m_antiAlias); +            break; + +        case CircularWaves2: +            circularWaves(&m_orgImage, &m_destImage, w/2, h/2, (double)l, (double)f, 25.0, true, m_antiAlias); +            break; + +        case PolarCoordinates: +            polarCoordinates(&m_orgImage, &m_destImage, true, m_antiAlias); +            break; + +        case UnpolarCoordinates: +            polarCoordinates(&m_orgImage, &m_destImage, false, m_antiAlias); +            break; + +        case Tile: +            tile(&m_orgImage, &m_destImage, 200-f, 200-f, l); +            break; +    } +} + +/* +    This code is shared by six methods. +    Write value of pixel w|h in data to pixel nw|nh in pResBits. +    Antialias if requested. +*/ +void DistortionFX::setPixelFromOther(int Width, int Height, bool sixteenBit, int bytesDepth, +                                            uchar *data, uchar *pResBits, +                                            int w, int h, double nw, double nh, bool AntiAlias) +{ +    Digikam::DColor color; +    int offset, offsetOther; + +    offset = getOffset(Width, w, h, bytesDepth); + +    if (AntiAlias) +    { +        uchar *ptr = pResBits + offset; +        if (sixteenBit) +        { +            unsigned short *ptr16 = (unsigned short *)ptr; +            Digikam::DImgImageFilters().pixelAntiAliasing16((unsigned short *)data, Width, Height, nw, nh, +                    ptr16+3, ptr16+2, ptr16+1, ptr16); +        } +        else +        { +            Digikam::DImgImageFilters().pixelAntiAliasing(data, Width, Height, nw, nh, +                    ptr+3, ptr+2, ptr+1, ptr); +        } +    } +    else +    { +        // we get the position adjusted +        offsetOther = getOffsetAdjusted(Width, Height, (int)nw, (int)nh, bytesDepth); +        // read color +        color.setColor(data + offsetOther, sixteenBit); +        // write color to destination +        color.setPixel(pResBits + offset); +    } +} + +/* Function to apply the fisheye effect backported from ImageProcessing version 2                                            + *                                                                                   + * data             => The image data in RGBA mode.                             + * Width            => Width of image.                           + * Height           => Height of image.     + * Coeff            => Distortion effect coeff. Positive value render 'Fish Eyes' effect,  + *                     and negative values render 'Caricature' effect. + * Antialias        => Smart bluring result.                        + *                                                                                   + * Theory           => This is a great effect if you take employee photos + *                     Its pure trigonometry. I think if you study hard the code you + *                     understand very well. + */ +void DistortionFX::fisheye(Digikam::DImg *orgImage, Digikam::DImg *destImage, double Coeff, bool AntiAlias) +{ +    if (Coeff == 0.0) return; + +    int Width       = orgImage->width(); +    int Height      = orgImage->height(); +    uchar* data     = orgImage->bits(); +    bool sixteenBit = orgImage->sixteenBit(); +    int bytesDepth  = orgImage->bytesDepth(); +    uchar* pResBits = destImage->bits(); + +    int h, w; +    double nh, nw, th, tw; + +    int progress; +    int nHalfW = Width / 2, nHalfH = Height / 2; + +    Digikam::DColor color; +    int offset; + +    double lfXScale = 1.0, lfYScale = 1.0; +    double lfRadius, lfRadMax, lfAngle, lfCoeff, lfCoeffStep = Coeff / 1000.0; + +    if (Width > Height) +        lfYScale = (double)Width / (double)Height; +    else if (Height > Width) +        lfXScale = (double)Height / (double)Width; + +    lfRadMax = (double)TQMAX(Height, Width) / 2.0; +    lfCoeff = lfRadMax / log (fabs (lfCoeffStep) * lfRadMax + 1.0); + +    // main loop + +    for (h = 0; !m_cancel && (h < Height); h++) +    { +        th = lfYScale * (double)(h - nHalfH); + +        for (w = 0; !m_cancel && (w < Width); w++) +        { +            tw = lfXScale * (double)(w - nHalfW); + +            // we find the distance from the center +            lfRadius = sqrt (th * th + tw * tw); + +            if (lfRadius < lfRadMax) +            { +                lfAngle = atan2 (th, tw); + +                if (Coeff > 0.0) +                    lfRadius = (exp (lfRadius / lfCoeff) - 1.0) / lfCoeffStep; +                else +                    lfRadius = lfCoeff * log (1.0 + (-1.0 * lfCoeffStep) * lfRadius); + +                nw = (double)nHalfW + (lfRadius / lfXScale) * cos (lfAngle); +                nh = (double)nHalfH + (lfRadius / lfYScale) * sin (lfAngle); + +                setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, h, nw, nh, AntiAlias); +            } +            else +            { +                // copy pixel +                offset = getOffset(Width, w, h, bytesDepth); +                color.setColor(data + offset, sixteenBit); +                color.setPixel(pResBits + offset); +            } +        } + +        // Update the progress bar in dialog. +        progress = (int) (((double)(h) * 100.0) / Height); + +        if (progress%5 == 0) +            postProgress(progress); +    } +} + +/* Function to apply the twirl effect backported from ImageProcessing version 2 + *                                                                                   + * data             => The image data in RGBA mode.                             + * Width            => Width of image.                           + * Height           => Height of image.                             + * Twirl            => Distance value. + * Antialias        => Smart bluring result.     + *                                                                                   + * Theory           => Take spiral studies, you will understand better, I'm studying + *                     hard on this effect, because it is not too fast. + */ +void DistortionFX::twirl(Digikam::DImg *orgImage, Digikam::DImg *destImage, int Twirl, bool AntiAlias) +{ +    // if twirl value is zero, we do nothing + +    if (Twirl == 0) +        return; + +    int Width       = orgImage->width(); +    int Height      = orgImage->height(); +    uchar* data     = orgImage->bits(); +    bool sixteenBit = orgImage->sixteenBit(); +    int bytesDepth  = orgImage->bytesDepth(); +    uchar* pResBits = destImage->bits(); + +    int h, w; +    double tw, th, nh, nw; + +    Digikam::DColor color; +    int offset; + +    int progress; +    int nHalfW = Width / 2, nHalfH = Height / 2; + +    double lfXScale = 1.0, lfYScale = 1.0; +    double lfAngle, lfNewAngle, lfAngleStep, lfAngleSum, lfCurrentRadius, lfRadMax; + +    if (Width > Height) +        lfYScale = (double)Width / (double)Height; +    else if (Height > Width) +        lfXScale = (double)Height / (double)Width; + +    // the angle step is twirl divided by 10000 +    lfAngleStep = Twirl / 10000.0; +    // now, we get the minimum radius +    lfRadMax = (double)TQMAX(Width, Height) / 2.0; + +    // main loop + +    for (h = 0; !m_cancel && (h < Height); h++) +    { +        th = lfYScale * (double)(h - nHalfH); + +        for (w = 0; !m_cancel && (w < Width); w++) +        { +            tw = lfXScale * (double)(w - nHalfW); + +            // now, we get the distance +            lfCurrentRadius = sqrt (th * th + tw * tw); + +            // if distance is less than maximum radius... +            if (lfCurrentRadius < lfRadMax) +            { +                // we find the angle from the center +                lfAngle = atan2 (th, tw); +                // we get the accumuled angle +                lfAngleSum = lfAngleStep * (-1.0 * (lfCurrentRadius - lfRadMax)); +                // ok, we sum angle with accumuled to find a new angle +                lfNewAngle = lfAngle + lfAngleSum; + +                // now we find the exact position's x and y +                nw = (double)nHalfW + cos (lfNewAngle) * (lfCurrentRadius / lfXScale); +                nh = (double)nHalfH + sin (lfNewAngle) * (lfCurrentRadius / lfYScale); + +                setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, h, nw, nh, AntiAlias); +            } +            else +            { +                // copy pixel +                offset = getOffset(Width, w, h, bytesDepth); +                color.setColor(data + offset, sixteenBit); +                color.setPixel(pResBits + offset); +            } +        } + +        // Update the progress bar in dialog. +        progress = (int) (((double)h * 100.0) / Height); + +        if (progress%5 == 0) +            postProgress(progress); +    } +} + +/* Function to apply the Cilindrical effect backported from ImageProcessing version 2 + *                                                                                   + * data             => The image data in RGBA mode.                             + * Width            => Width of image.                           + * Height           => Height of image.                             + * Coeff            => Cilindrical value. + * Horizontal       => Apply horizontally. + * Vertical         => Apply vertically. + * Antialias        => Smart bluring result.  + *                                                                                   + * Theory           => This is a great effect, similar to Spherize (Photoshop).     + *                     If you understand FishEye, you will understand Cilindrical     + *                     FishEye apply a logarithm function using a sphere radius,      + *                     Spherize use the same function but in a rectangular         + *                     environment. + */ +void DistortionFX::cilindrical(Digikam::DImg *orgImage, Digikam::DImg *destImage, double Coeff, +                               bool Horizontal, bool Vertical, bool AntiAlias) + +{ +    if ((Coeff == 0.0) || (! (Horizontal || Vertical))) +        return; + +    int Width       = orgImage->width(); +    int Height      = orgImage->height(); +    uchar* data     = orgImage->bits(); +    bool sixteenBit = orgImage->sixteenBit(); +    int bytesDepth  = orgImage->bytesDepth(); +    uchar* pResBits = destImage->bits(); + +    int progress; + +    int h, w; +    double nh, nw; + +    int nHalfW = Width / 2, nHalfH = Height / 2; +    double lfCoeffX = 1.0, lfCoeffY = 1.0, lfCoeffStep = Coeff / 1000.0; + +    if (Horizontal) +        lfCoeffX = (double)nHalfW / log (fabs (lfCoeffStep) * nHalfW + 1.0); +    if (Vertical) +        lfCoeffY = (double)nHalfH / log (fabs (lfCoeffStep) * nHalfH + 1.0); + +    // initial copy +    memcpy (pResBits, data, orgImage->numBytes()); + +    // main loop + +    for (h = 0; !m_cancel && (h < Height); h++) +    { +        for (w = 0; !m_cancel && (w < Width); w++) +        { +            // we find the distance from the center +            nh = fabs ((double)(h - nHalfH)); +            nw = fabs ((double)(w - nHalfW)); + +            if (Horizontal) +            { +                if (Coeff > 0.0) +                    nw = (exp (nw / lfCoeffX) - 1.0) / lfCoeffStep; +                else +                    nw = lfCoeffX * log (1.0 + (-1.0 * lfCoeffStep) * nw); +            } + +            if (Vertical) +            { +                if (Coeff > 0.0) +                    nh = (exp (nh / lfCoeffY) - 1.0) / lfCoeffStep; +                else +                    nh = lfCoeffY * log (1.0 + (-1.0 * lfCoeffStep) * nh); +            } + +            nw = (double)nHalfW + ((w >= nHalfW) ? nw : -nw); +            nh = (double)nHalfH + ((h >= nHalfH) ? nh : -nh); + +            setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, h, nw, nh, AntiAlias); +        } + +        // Update the progress bar in dialog. +        progress = (int) (((double)h * 100.0) / Height); + +        if (progress%5 == 0) +            postProgress(progress); +    } +} + +/* Function to apply the Multiple Corners effect backported from ImageProcessing version 2 + *                                                                                   + * data             => The image data in RGBA mode.                             + * Width            => Width of image.                           + * Height           => Height of image.        + * Factor           => nb corners. + * Antialias        => Smart bluring result.                       + *                                                                                   + * Theory           => This is an amazing function, you've never seen this before.  + *                     I was testing some trigonometric functions, and I saw that if   + *                     I multiply the angle by 2, the result is an image like this    + *                     If we multiply by 3, we can create the SixCorners effect.  + */ +void DistortionFX::multipleCorners(Digikam::DImg *orgImage, Digikam::DImg *destImage, int Factor, bool AntiAlias) +{ +    if (Factor == 0) return; + +    int Width       = orgImage->width(); +    int Height      = orgImage->height(); +    uchar* data     = orgImage->bits(); +    bool sixteenBit = orgImage->sixteenBit(); +    int bytesDepth  = orgImage->bytesDepth(); +    uchar* pResBits = destImage->bits(); + +    int h, w; +    double nh, nw; +    int progress; + +    int nHalfW = Width / 2, nHalfH = Height / 2; +    double lfAngle, lfNewRadius, lfCurrentRadius, lfRadMax; + +    lfRadMax = sqrt (Height * Height + Width * Width) / 2.0; + +    // main loop + +    for (h = 0; !m_cancel && (h < Height); h++) +    { +        for (w = 0; !m_cancel && (w < Width); w++) +        { +            // we find the distance from the center +            nh = nHalfH - h; +            nw = nHalfW - w; + +            // now, we get the distance +            lfCurrentRadius = sqrt (nh * nh + nw * nw); +            // we find the angle from the center +            lfAngle = atan2 (nh, nw) * (double)Factor; + +            // ok, we sum angle with accumuled to find a new angle +            lfNewRadius = lfCurrentRadius * lfCurrentRadius / lfRadMax; + +            // now we find the exact position's x and y +            nw = (double)nHalfW - (cos (lfAngle) * lfNewRadius); +            nh = (double)nHalfH - (sin (lfAngle) * lfNewRadius); + +            setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, h, nw, nh, AntiAlias); +        } + +        // Update the progress bar in dialog. +        progress = (int) (((double)h * 100.0) / Height); + +        if (progress%5 == 0) +            postProgress(progress); +    } +} + +/* Function to apply the Polar Coordinates effect backported from ImageProcessing version 2 + *                                                                                   + * data             => The image data in RGBA mode.                             + * Width            => Width of image.                           + * Height           => Height of image. + * Type             => if true Polar Coordinate to Polar else inverse. + * Antialias        => Smart bluring result.                       + *                                                                                   + * Theory           => Similar to PolarCoordinates from Photoshop. We apply the polar    + *                     transformation in a proportional (Height and Width) radius. + */ +void DistortionFX::polarCoordinates(Digikam::DImg *orgImage, Digikam::DImg *destImage, bool Type, bool AntiAlias) +{ +    int Width       = orgImage->width(); +    int Height      = orgImage->height(); +    uchar* data     = orgImage->bits(); +    bool sixteenBit = orgImage->sixteenBit(); +    int bytesDepth  = orgImage->bytesDepth(); +    uchar* pResBits = destImage->bits(); + +    int h, w; +    double nh, nw, th, tw; +    int progress; + +    int nHalfW = Width / 2, nHalfH = Height / 2; +    double lfXScale = 1.0, lfYScale = 1.0; +    double lfAngle, lfRadius, lfRadMax; + +    if (Width > Height) +        lfYScale = (double)Width / (double)Height; +    else if (Height > Width) +        lfXScale = (double)Height / (double)Width; + +    lfRadMax = (double)TQMAX(Height, Width) / 2.0; + +    // main loop + +    for (h = 0; !m_cancel && (h < Height); h++) +    { +        th = lfYScale * (double)(h - nHalfH); + +        for (w = 0; !m_cancel && (w < Width); w++) +        { +            tw = lfXScale * (double)(w - nHalfW); + +            if (Type) +            { +                // now, we get the distance +                lfRadius = sqrt (th * th + tw * tw); +                // we find the angle from the center +                lfAngle = atan2 (tw, th); + +                // now we find the exact position's x and y +                nh = lfRadius * (double) Height / lfRadMax; +                nw =  lfAngle * (double)  Width / (2 * M_PI); + +                nw = (double)nHalfW + nw; +            } +            else +            { +                lfRadius = (double)(h) * lfRadMax / (double)Height; +                lfAngle  = (double)(w) * (2 * M_PI) / (double) Width; + +                nw = (double)nHalfW - (lfRadius / lfXScale) * sin (lfAngle); +                nh = (double)nHalfH - (lfRadius / lfYScale) * cos (lfAngle); +            } + +            setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, h, nw, nh, AntiAlias); +        } + +        // Update the progress bar in dialog. +        progress = (int) (((double)h * 100.0) / Height); + +        if (progress%5 == 0) +            postProgress(progress); +    } +} + +/* Function to apply the circular waves effect backported from ImageProcessing version 2                                            + *                                                                                   + * data             => The image data in RGBA mode.                             + * Width            => Width of image.                           + * Height           => Height of image.      + * X, Y             => Position of circle center on the image.                        + * Amplitude        => Sinoidal maximum height                                         + * Frequency        => Frequency value. + * Phase            => Phase value. + * WavesType        => If true  the amplitude is proportional to radius. + * Antialias        => Smart bluring result.                       + *                                                                                   + * Theory           => Similar to Waves effect, but here I apply a senoidal function + *                     with the angle point.                                                       + */ +void DistortionFX::circularWaves(Digikam::DImg *orgImage, Digikam::DImg *destImage, int X, int Y, double Amplitude,  +                                 double Frequency, double Phase, bool WavesType, bool AntiAlias) +{ +    if (Amplitude < 0.0) Amplitude = 0.0; +    if (Frequency < 0.0) Frequency = 0.0; + +    int Width       = orgImage->width(); +    int Height      = orgImage->height(); +    uchar* data     = orgImage->bits(); +    bool sixteenBit = orgImage->sixteenBit(); +    int bytesDepth  = orgImage->bytesDepth(); +    uchar* pResBits = destImage->bits(); + +    int h, w; +    double nh, nw; +    int progress; + +    double lfRadius, lfRadMax, lfNewAmp = Amplitude; +    double lfFreqAngle = Frequency * ANGLE_RATIO; + +    Phase *= ANGLE_RATIO; + +    lfRadMax = sqrt (Height * Height + Width * Width); + +    for (h = 0; !m_cancel && (h < Height); h++) +    { +        for (w = 0; !m_cancel && (w < Width); w++) +        { +            nw = X - w; +            nh = Y - h; + +            lfRadius = sqrt (nw * nw + nh * nh); + +            if (WavesType) +                lfNewAmp = Amplitude * lfRadius / lfRadMax; + +            nw = (double)w + lfNewAmp * sin(lfFreqAngle * lfRadius + Phase); +            nh = (double)h + lfNewAmp * cos(lfFreqAngle * lfRadius + Phase); + +            setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, h, nw, nh, AntiAlias); +        } + +        // Update the progress bar in dialog. +        progress = (int) (((double)h * 100.0) / Height); + +        if (progress%5 == 0) +            postProgress(progress); +    } +} + +/* Function to apply the waves effect                                             + *                                                                                   + * data             => The image data in RGBA mode.                             + * Width            => Width of image.                           + * Height           => Height of image.                             + * Amplitude        => Sinoidal maximum height.                                         + * Frequency        => Frequency value.                                                 + * FillSides        => Like a boolean variable.                                         + * Direction        => Vertical or horizontal flag.                                     + *                                                                                     + * Theory           => This is an amazing effect, very funny, and very simple to     + *                     understand. You just need understand how sin and cos works.    + */ +void DistortionFX::waves(Digikam::DImg *orgImage, Digikam::DImg *destImage, +                         int Amplitude, int Frequency, +                         bool FillSides, bool Direction) +{ +    if (Amplitude < 0) Amplitude = 0; +    if (Frequency < 0) Frequency = 0; + +    int Width       = orgImage->width(); +    int Height      = orgImage->height(); + +    int progress; +    int h, w; + +    if (Direction)        // Horizontal +    { +        int tx; + +        for (h = 0; !m_cancel && (h < Height); h++) +        { +            tx = lround(Amplitude * sin ((Frequency * 2) * h * (M_PI / 180))); +            destImage->bitBltImage(orgImage, 0, h,  Width, 1,  tx, h); + +            if (FillSides) +            { +                destImage->bitBltImage(orgImage, Width - tx, h,  tx, 1,  0, h); +                destImage->bitBltImage(orgImage, 0, h,  Width - (Width - 2 * Amplitude + tx), 1,  Width + tx, h); +            } + +            // Update the progress bar in dialog. +            progress = (int) (((double)h * 100.0) / Height); + +            if (progress%5 == 0) +                postProgress(progress); +        } +    } +    else +    { +        int ty; + +        for (w = 0; !m_cancel && (w < Width); w++) +        { +            ty = lround(Amplitude * sin ((Frequency * 2) * w * (M_PI / 180))); +            destImage->bitBltImage(orgImage, w, 0, 1, Height, w, ty); + +            if (FillSides) +            { +                destImage->bitBltImage(orgImage, w, Height - ty,  1, ty,  w, 0); +                destImage->bitBltImage(orgImage, w, 0,  1, Height - (Height - 2 * Amplitude + ty),  w, Height + ty); +            } + +            // Update the progress bar in dialog. +            progress = (int) (((double)w * 100.0) / Width); + +            if (progress%5 == 0) +                postProgress(progress); +        } +    } +} + +/* Function to apply the block waves effect                                             + *                                                                                   + * data             => The image data in RGBA mode.                             + * Width            => Width of image.                           + * Height           => Height of image.                             + * Amplitude        => Sinoidal maximum height                                         + * Frequency        => Frequency value                                                 + * Mode             => The mode to be applied.                                        + *                                                                                   + * Theory           => This is an amazing effect, very funny when amplitude and      + *                     frequency are small values.                                   + */ +void DistortionFX::blockWaves(Digikam::DImg *orgImage, Digikam::DImg *destImage, +                              int Amplitude, int Frequency, bool Mode) +{ +    if (Amplitude < 0) Amplitude = 0; +    if (Frequency < 0) Frequency = 0; + +    int Width       = orgImage->width(); +    int Height      = orgImage->height(); +    uchar* data     = orgImage->bits(); +    bool sixteenBit = orgImage->sixteenBit(); +    int bytesDepth  = orgImage->bytesDepth(); +    uchar* pResBits = destImage->bits(); + +    int nw, nh, progress; +    double Radius; + +    Digikam::DColor color; +    int offset, offsetOther; + +    int nHalfW = Width / 2, nHalfH = Height / 2; + +    for (int w = 0; !m_cancel && (w < Width); w++) +    { +        for (int h = 0; !m_cancel && (h < Height); h++) +        { +            nw = nHalfW - w; +            nh = nHalfH - h; + +            Radius = sqrt (nw * nw + nh * nh); + +            if (Mode) +            { +                nw = (int)(w + Amplitude * sin (Frequency * nw * (M_PI / 180))); +                nh = (int)(h + Amplitude * cos (Frequency * nh * (M_PI / 180))); +            } +            else +            { +                nw = (int)(w + Amplitude * sin (Frequency * w * (M_PI / 180))); +                nh = (int)(h + Amplitude * cos (Frequency * h * (M_PI / 180))); +            } + +            offset = getOffset(Width, w, h, bytesDepth); +            offsetOther = getOffsetAdjusted(Width, Height, (int)nw, (int)nh, bytesDepth); + +            // read color +            color.setColor(data + offsetOther, sixteenBit); +            // write color to destination +            color.setPixel(pResBits + offset); +        } + +        // Update the progress bar in dialog. +        progress = (int) (((double)w * 100.0) / Width); + +        if (progress%5 == 0) +            postProgress(progress); +    } +} + +/* Function to apply the tile effect                                             + *                                                                                   + * data             => The image data in RGBA mode.                             + * Width            => Width of image.                           + * Height           => Height of image.                             + * WSize            => Tile Width                                                         + * HSize            => Tile Height                                                       + * Random           => Maximum random value                                         + *                                                                                     + * Theory           => Similar to Tile effect from Photoshop and very easy to         + *                     understand. We get a rectangular area using WSize and HSize and     + *                     replace in a position with a random distance from the original     + *                     position.                                                     + */ +void DistortionFX::tile(Digikam::DImg *orgImage, Digikam::DImg *destImage, +                        int WSize, int HSize, int Random) +{ +    if (WSize < 1)  WSize = 1; +    if (HSize < 1)  HSize = 1; +    if (Random < 1) Random = 1; + +    int Width       = orgImage->width(); +    int Height      = orgImage->height(); + +    TQDateTime dt = TQDateTime::currentDateTime(); +    TQDateTime Y2000( TQDate(2000, 1, 1), TQTime(0, 0, 0) ); +    uint seed = dt.secsTo(Y2000); + +    int tx, ty, h, w, progress; + +    for (h = 0; !m_cancel && (h < Height); h += HSize) +    { +        for (w = 0; !m_cancel && (w < Width); w += WSize) +        { +            tx = (int)(rand_r(&seed) % Random) - (Random / 2); +            ty = (int)(rand_r(&seed) % Random) - (Random / 2); +            destImage->bitBltImage(orgImage, w, h,   WSize, HSize,   w + tx, h + ty); +        } + +        // Update the progress bar in dialog. +        progress = (int)(((double)h * 100.0) / Height); + +        if (progress%5 == 0) +            postProgress(progress); +    } +} + +// UNUSED +/* Function to return the maximum radius with a determined angle                     + *                                                                                   + * Height           => Height of the image                                          + * Width            => Width of the image                                            + * Angle            => Angle to analize the maximum radius                           + *                                                                                   + * Theory           => This function calcule the maximum radius to that angle       + *                     so, we can build an oval circunference                         + */                                                                                    + /* +double DistortionFX::maximumRadius(int Height, int Width, double Angle) +{ +    double MaxRad, MinRad; +    double Radius, DegAngle = fabs (Angle * 57.295);    // Rads -> Degrees + +    MinRad = TQMIN (Height, Width) / 2.0;                // Gets the minor radius +    MaxRad = TQMAX (Height, Width) / 2.0;                // Gets the major radius + +    // Find the quadrant between -PI/2 and PI/2 +    if (DegAngle > 90.0) +        Radius = proportionalValue (MinRad, MaxRad, (DegAngle * (255.0 / 90.0))); +    else +        Radius = proportionalValue (MaxRad, MinRad, ((DegAngle - 90.0) * (255.0 / 90.0))); +    return (Radius); +} + */ + +}  // NameSpace DigikamDistortionFXImagesPlugin diff --git a/src/imageplugins/distortionfx/distortionfx.h b/src/imageplugins/distortionfx/distortionfx.h new file mode 100644 index 00000000..073f4df2 --- /dev/null +++ b/src/imageplugins/distortionfx/distortionfx.h @@ -0,0 +1,149 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date        : 2005-07-18 + * Description : Distortion FX threaded image filter. + * + * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com> + * Copyright (C) 2006-2007 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> + * + * Original Distortion algorithms copyrighted 2004-2005 by  + * Pieter Z. Voloshyn <pieter dot voloshyn at gmail dot com>. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) + * any later version. + *  + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + *  + * ============================================================ */ +   +#ifndef DISTORTION_FX_H +#define DISTORTION_FX_H + +// TQt includes. + +#include <tqsize.h> + +// Digikam includes. + +#include "dimgthreadedfilter.h" + +namespace DigikamDistortionFXImagesPlugin +{ + +class DistortionFX : public Digikam::DImgThreadedFilter +{ + +public: + +    DistortionFX(Digikam::DImg *orgImage, TQObject *parent=0, int effectType=0, +                 int level=0, int iteration=0, bool antialiasing=true); + +    ~DistortionFX(){}; + +public: + +    enum DistortionFXTypes +    { +        FishEye=0, +        Twirl, +        CilindricalHor, +        CilindricalVert, +        CilindricalHV, +        Caricature, +        MultipleCorners, +        WavesHorizontal, +        WavesVertical, +        BlockWaves1, +        BlockWaves2, +        CircularWaves1, +        CircularWaves2, +        PolarCoordinates, +        UnpolarCoordinates, +        Tile +    }; + +private: + +    virtual void filterImage(void); + +    // Backported from ImageProcessing version 2 +    void fisheye(Digikam::DImg *orgImage, Digikam::DImg *destImage, double Coeff, bool AntiAlias=true); +    void twirl(Digikam::DImg *orgImage, Digikam::DImg *destImage, int Twirl, bool AntiAlias=true); +    void cilindrical(Digikam::DImg *orgImage, Digikam::DImg *destImage, double Coeff,  +                     bool Horizontal, bool Vertical, bool AntiAlias=true); +    void multipleCorners(Digikam::DImg *orgImage, Digikam::DImg *destImage, int Factor, bool AntiAlias=true); +    void polarCoordinates(Digikam::DImg *orgImage, Digikam::DImg *destImage, bool Type, bool AntiAlias=true); +    void circularWaves(Digikam::DImg *orgImage, Digikam::DImg *destImage, int X, int Y, double Amplitude,  +                       double Frequency, double Phase, bool WavesType, bool AntiAlias=true); + +    // Backported from ImageProcessing version 1 +    void waves(Digikam::DImg *orgImage, Digikam::DImg *destImage, int Amplitude, int Frequency,  +               bool FillSides, bool Direction); +    void blockWaves(Digikam::DImg *orgImage, Digikam::DImg *destImage, int Amplitude, int Frequency, bool Mode); +    void tile(Digikam::DImg *orgImage, Digikam::DImg *destImage, int WSize, int HSize, int Random); + +    void setPixelFromOther(int Width, int Height, bool sixteenBit, int bytesDepth, +                           uchar *data, uchar *pResBits, +                           int w, int h, double nw, double nh, bool AntiAlias); +    /* +    //UNUSED + +    inline double maximumRadius(int Height, int Width, double Angle); + +    // This function does the same thing that ShadeColors function but using double variables. +    inline double proportionalValue (double DestValue, double SrcValue, double Shade) +    { +        if (Shade == 0.0) return DestValue; +        if (Shade == 255.0) return SrcValue; +        return ((DestValue * (255.0 - Shade) + SrcValue * Shade) / 256.0); +    }; +    */ + +    // Return the limit defined the max and min values. +    inline int Lim_Max(int Now, int Up, int Max)  +    { +        --Max; +        while (Now > Max - Up) --Up; +        return (Up); +    }; + +    inline bool isInside (int Width, int Height, int X, int Y) +    { +        bool bIsWOk = ((X < 0) ? false : (X >= Width ) ? false : true); +        bool bIsHOk = ((Y < 0) ? false : (Y >= Height) ? false : true); +        return (bIsWOk && bIsHOk); +    }; + +    inline int getOffset(int Width, int X, int Y, int bytesDepth) +    { +        return (Y * Width * bytesDepth) + (X * bytesDepth); +    }; + +    inline int getOffsetAdjusted(int Width, int Height, int X, int Y, int bytesDepth) +    { +        X = (X < 0) ?  0  :  ((X >= Width ) ? (Width  - 1) : X); +        Y = (Y < 0) ?  0  :  ((Y >= Height) ? (Height - 1) : Y); +        return getOffset(Width, X, Y, bytesDepth); +    }; + +private: + +    bool m_antiAlias; + +    int  m_level; +    int  m_iteration; +    int  m_effectType; +}; + +}  // NameSpace DigikamDistortionFXImagesPlugin + +#endif /* DISTORTION_FX_H */ diff --git a/src/imageplugins/distortionfx/distortionfxtool.cpp b/src/imageplugins/distortionfx/distortionfxtool.cpp new file mode 100644 index 00000000..45ff0e45 --- /dev/null +++ b/src/imageplugins/distortionfx/distortionfxtool.cpp @@ -0,0 +1,398 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date        : 2005-02-11 + * Description : a plugin to apply Distortion FX to an image. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * Copyright (C) 2006-2008 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> + * + * Original Distortion algorithms copyrighted 2004-2005 by + * Pieter Z. Voloshyn <pieter dot voloshyn at gmail dot com>. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * ============================================================ */ + +// TQt includes. + +#include <tqframe.h> +#include <tqimage.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqspinbox.h> +#include <tqwhatsthis.h> + +// KDE includes. + +#include <tdeaboutdata.h> +#include <tdeapplication.h> +#include <tdeconfig.h> +#include <kcursor.h> +#include <khelpmenu.h> +#include <kiconloader.h> +#include <tdelocale.h> +#include <kprogress.h> +#include <kstandarddirs.h> + +// LibKDcraw includes. + +#include <libkdcraw/rnuminput.h> +#include <libkdcraw/rcombobox.h> + +// Local includes. + +#include "daboutdata.h" +#include "ddebug.h" +#include "dimg.h" +#include "editortoolsettings.h" +#include "imageiface.h" +#include "imagewidget.h" +#include "distortionfx.h" +#include "distortionfxtool.h" +#include "distortionfxtool.moc" + +using namespace KDcrawIface; +using namespace Digikam; + +namespace DigikamDistortionFXImagesPlugin +{ + +DistortionFXTool::DistortionFXTool(TQObject* parent) +                : EditorToolThreaded(parent) +{ +    setName("distortionfx"); +    setToolName(i18n("Distortion Effects")); +    setToolIcon(SmallIcon("distortionfx")); + +    m_previewWidget = new ImageWidget("distortionfx Tool", 0, +                                      i18n("<p>This is the preview of the distortion effect " +                                           "applied to the photograph."), +                                      false, ImageGuideWidget::HVGuideMode); + +    setToolView(m_previewWidget); + +    // ------------------------------------------------------------- + +    m_gboxSettings = new EditorToolSettings(EditorToolSettings::Default| +                                            EditorToolSettings::Ok| +                                            EditorToolSettings::Cancel, +                                            EditorToolSettings::ColorGuide); + +    TQGridLayout* gridSettings = new TQGridLayout(m_gboxSettings->plainPage(), 7, 2); + +    m_effectTypeLabel = new TQLabel(i18n("Type:"), m_gboxSettings->plainPage()); + +    m_effectType = new RComboBox(m_gboxSettings->plainPage()); +    m_effectType->insertItem(i18n("Fish Eyes")); +    m_effectType->insertItem(i18n("Twirl")); +    m_effectType->insertItem(i18n("Cylindrical Hor.")); +    m_effectType->insertItem(i18n("Cylindrical Vert.")); +    m_effectType->insertItem(i18n("Cylindrical H/V.")); +    m_effectType->insertItem(i18n("Caricature")); +    m_effectType->insertItem(i18n("Multiple Corners")); +    m_effectType->insertItem(i18n("Waves Hor.")); +    m_effectType->insertItem(i18n("Waves Vert.")); +    m_effectType->insertItem(i18n("Block Waves 1")); +    m_effectType->insertItem(i18n("Block Waves 2")); +    m_effectType->insertItem(i18n("Circular Waves 1")); +    m_effectType->insertItem(i18n("Circular Waves 2")); +    m_effectType->insertItem(i18n("Polar Coordinates")); +    m_effectType->insertItem(i18n("Unpolar Coordinates")); +    m_effectType->insertItem(i18n("Tile")); +    m_effectType->setDefaultItem(DistortionFX::FishEye); +    TQWhatsThis::add( m_effectType, i18n("<p>Here, select the type of effect to apply to the image.<p>" +                                        "<b>Fish Eyes</b>: warps the photograph around a 3D spherical shape to " +                                        "reproduce the common photograph 'Fish Eyes' effect.<p>" +                                        "<b>Twirl</b>: spins the photograph to produce a Twirl pattern.<p>" +                                        "<b>Cylinder Hor.</b>: warps the photograph around a horizontal cylinder.<p>" +                                        "<b>Cylinder Vert.</b>: warps the photograph around a vertical cylinder.<p>" +                                        "<b>Cylinder H/V.</b>: warps the photograph around 2 cylinders, vertical " +                                        "and horizontal.<p>" +                                        "<b>Caricature</b>: distorts the photograph with the 'Fish Eyes' effect inverted.<p>" +                                        "<b>Multiple Corners</b>: splits the photograph like a multiple corners pattern.<p>" +                                        "<b>Waves Horizontal</b>: distorts the photograph with horizontal waves.<p>" +                                        "<b>Waves Vertical</b>: distorts the photograph with vertical waves.<p>" +                                        "<b>Block Waves 1</b>: divides the image into cells and makes it look as " +                                        "if it is being viewed through glass blocks.<p>" +                                        "<b>Block Waves 2</b>: like Block Waves 1 but with another version " +                                        "of glass blocks distortion.<p>" +                                        "<b>Circular Waves 1</b>: distorts the photograph with circular waves.<p>" +                                        "<b>Circular Waves 2</b>: another variation of the Circular Waves effect.<p>" +                                        "<b>Polar Coordinates</b>: converts the photograph from rectangular " +                                        "to polar coordinates.<p>" +                                        "<b>Unpolar Coordinates</b>: the Polar Coordinates effect inverted.<p>" +                                        "<b>Tile</b>: splits the photograph into square blocks and moves " +                                        "them randomly inside the image.<p>" +                                        )); + +    m_levelLabel = new TQLabel(i18n("Level:"), m_gboxSettings->plainPage()); +    m_levelInput = new RIntNumInput(m_gboxSettings->plainPage()); +    m_levelInput->setRange(0, 100, 1); +    m_levelInput->setDefaultValue(50); +    TQWhatsThis::add( m_levelInput, i18n("<p>Set here the level of the effect.")); + + +    m_iterationLabel = new TQLabel(i18n("Iteration:"), m_gboxSettings->plainPage()); +    m_iterationInput = new RIntNumInput(m_gboxSettings->plainPage()); +    m_iterationInput->setRange(0, 100, 1); +    m_iterationInput->setDefaultValue(10); +    TQWhatsThis::add( m_iterationInput, i18n("<p>This value controls the iterations to use for Waves, " +                                            "Tile, and Neon effects.")); + +    gridSettings->addMultiCellWidget(m_effectTypeLabel,     0, 0, 0, 1); +    gridSettings->addMultiCellWidget(m_effectType,          1, 1, 0, 1); +    gridSettings->addMultiCellWidget(m_levelLabel,          2, 2, 0, 1); +    gridSettings->addMultiCellWidget(m_levelInput,          3, 3, 0, 1); +    gridSettings->addMultiCellWidget(m_iterationLabel,      4, 4, 0, 1); +    gridSettings->addMultiCellWidget(m_iterationInput,      5, 5, 0, 1); +    gridSettings->setRowStretch(6, 10); + +    setToolSettings(m_gboxSettings); +    init(); + +    // ------------------------------------------------------------- + +    connect(m_effectType, TQ_SIGNAL(activated(int)), +            this, TQ_SLOT(slotEffectTypeChanged(int))); + +    connect(m_levelInput, TQ_SIGNAL(valueChanged(int)), +            this, TQ_SLOT(slotTimer())); + +    connect(m_iterationInput, TQ_SIGNAL(valueChanged(int)), +            this, TQ_SLOT(slotTimer())); + +    connect(m_gboxSettings, TQ_SIGNAL(signalColorGuideChanged()), +            this, TQ_SLOT(slotColorGuideChanged())); +} + +DistortionFXTool::~DistortionFXTool() +{ +} + +void DistortionFXTool::slotColorGuideChanged() +{ +    m_previewWidget->slotChangeGuideColor(m_gboxSettings->guideColor()); +    m_previewWidget->slotChangeGuideSize(m_gboxSettings->guideSize()); +} + +void DistortionFXTool::renderingFinished() +{ +    m_effectTypeLabel->setEnabled(true); +    m_effectType->setEnabled(true); +    m_levelInput->setEnabled(true); +    m_levelLabel->setEnabled(true); +    m_iterationInput->setEnabled(true); +    m_iterationLabel->setEnabled(true); + +    switch (m_effectType->currentItem()) +    { +        case DistortionFX::FishEye: +        case DistortionFX::Twirl: +        case DistortionFX::CilindricalHor: +        case DistortionFX::CilindricalVert: +        case DistortionFX::CilindricalHV: +        case DistortionFX::Caricature: +        case DistortionFX::MultipleCorners: +            break; + +        case DistortionFX::PolarCoordinates: +        case DistortionFX::UnpolarCoordinates: +            m_levelInput->setEnabled(false); +            m_levelLabel->setEnabled(false); +            break; + +        case DistortionFX::WavesHorizontal: +        case DistortionFX::WavesVertical: +        case DistortionFX::BlockWaves1: +        case DistortionFX::BlockWaves2: +        case DistortionFX::CircularWaves1: +        case DistortionFX::CircularWaves2: +        case DistortionFX::Tile: +            m_iterationInput->setEnabled(true); +            m_iterationLabel->setEnabled(true); +            break; +    } +} + +void DistortionFXTool::readSettings(void) +{ +    TDEConfig *config = kapp->config(); +    config->setGroup("distortionfx Tool"); + +    m_effectType->blockSignals(true); +    m_iterationInput->blockSignals(true); +    m_levelInput->blockSignals(true); + +    m_effectType->setCurrentItem(config->readNumEntry("EffectType", +                                 m_effectType->defaultItem())); +    m_iterationInput->setValue(config->readNumEntry("IterationAjustment", +                               m_iterationInput->defaultValue())); +    m_levelInput->setValue(config->readNumEntry("LevelAjustment", +                           m_levelInput->defaultValue())); + +    m_effectType->blockSignals(false); +    m_iterationInput->blockSignals(false); +    m_levelInput->blockSignals(false); + +    slotEffect(); +} + +void DistortionFXTool::writeSettings(void) +{ +    TDEConfig *config = kapp->config(); +    config->setGroup("distortionfx Tool"); +    config->writeEntry("EffectType", m_effectType->currentItem()); +    config->writeEntry("IterationAjustment", m_iterationInput->value()); +    config->writeEntry("LevelAjustment", m_levelInput->value()); +    m_previewWidget->writeSettings(); +    config->sync(); +} + +void DistortionFXTool::slotResetSettings() +{ +    m_effectType->blockSignals(true); +    m_levelInput->blockSignals(true); +    m_iterationInput->blockSignals(true); + +    m_levelInput->slotReset(); +    m_iterationInput->slotReset(); +    m_effectType->slotReset(); +    slotEffectTypeChanged(m_effectType->defaultItem()); + +    m_effectType->blockSignals(false); +    m_levelInput->blockSignals(false); +    m_iterationInput->blockSignals(false); +} + +void DistortionFXTool::slotEffectTypeChanged(int type) +{ +    m_levelInput->setEnabled(true); +    m_levelLabel->setEnabled(true); + +    m_levelInput->blockSignals(true); +    m_iterationInput->blockSignals(true); +    m_levelInput->setRange(0, 100, 1); +    m_levelInput->setValue(25); + +    switch (type) +    { +        case DistortionFX::Twirl: +            m_levelInput->setRange(-50, 50, 1); +            m_levelInput->setValue(10); +            break; + +        case DistortionFX::FishEye: +        case DistortionFX::CilindricalHor: +        case DistortionFX::CilindricalVert: +        case DistortionFX::CilindricalHV: +        case DistortionFX::Caricature: +            m_levelInput->setRange(0, 200, 1); +            m_levelInput->setValue(50); +            break; + +        case DistortionFX::MultipleCorners: +            m_levelInput->setRange(1, 10, 1); +            m_levelInput->setValue(4); +            break; + +        case DistortionFX::WavesHorizontal: +        case DistortionFX::WavesVertical: +        case DistortionFX::BlockWaves1: +        case DistortionFX::BlockWaves2: +        case DistortionFX::CircularWaves1: +        case DistortionFX::CircularWaves2: +        case DistortionFX::Tile: +            m_iterationInput->setEnabled(true); +            m_iterationLabel->setEnabled(true); +            m_iterationInput->setRange(0, 200, 1); +            m_iterationInput->setValue(10); +            break; + +        case DistortionFX::PolarCoordinates: +        case DistortionFX::UnpolarCoordinates: +            m_levelInput->setEnabled(false); +            m_levelLabel->setEnabled(false); +            break; +    } + +    m_levelInput->blockSignals(false); +    m_iterationInput->blockSignals(false); + +    slotEffect(); +} + +void DistortionFXTool::prepareEffect() +{ +    m_effectTypeLabel->setEnabled(false); +    m_effectType->setEnabled(false); +    m_levelInput->setEnabled(false); +    m_levelLabel->setEnabled(false); +    m_iterationInput->setEnabled(false); +    m_iterationLabel->setEnabled(false); + +    int l = m_levelInput->value(); +    int f = m_iterationInput->value(); +    int e = m_effectType->currentItem(); + +    ImageIface* iface = m_previewWidget->imageIface(); + +    uchar *data = iface->getPreviewImage(); +    DImg image(iface->previewWidth(), iface->previewHeight(), iface->previewSixteenBit(), +                        iface->previewHasAlpha(), data); +    delete [] data; + +    setFilter(dynamic_cast<DImgThreadedFilter *> (new DistortionFX(&image, this, e, l, f))); +} + +void DistortionFXTool::prepareFinal() +{ +    m_effectTypeLabel->setEnabled(false); +    m_effectType->setEnabled(false); +    m_levelInput->setEnabled(false); +    m_levelLabel->setEnabled(false); +    m_iterationInput->setEnabled(false); +    m_iterationLabel->setEnabled(false); + +    int l = m_levelInput->value(); +    int f = m_iterationInput->value(); +    int e = m_effectType->currentItem(); + +    ImageIface iface(0, 0); + +    setFilter(dynamic_cast<DImgThreadedFilter *> (new DistortionFX(iface.getOriginalImg(), this, e, l, f))); +} + +void DistortionFXTool::putPreviewData(void) +{ +    ImageIface* iface = m_previewWidget->imageIface(); + +    DImg imDest = filter()->getTargetImage() +            .smoothScale(iface->previewWidth(), iface->previewHeight()); +    iface->putPreviewImage(imDest.bits()); + +    m_previewWidget->updatePreview(); +} + +void DistortionFXTool::putFinalData(void) +{ +    ImageIface iface(0, 0); +    DImg targetImage = filter()->getTargetImage(); +    iface.putOriginalImage(i18n("Distortion Effects"), +            targetImage.bits(), +            targetImage.width(), targetImage.height()); +} + +}  // NameSpace DigikamDistortionFXImagesPlugin + diff --git a/src/imageplugins/distortionfx/distortionfxtool.h b/src/imageplugins/distortionfx/distortionfxtool.h new file mode 100644 index 00000000..bcdd6088 --- /dev/null +++ b/src/imageplugins/distortionfx/distortionfxtool.h @@ -0,0 +1,96 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date        : 2005-02-11 + * Description : a plugin to apply Distortion FX to an image. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * Copyright (C) 2006-2008 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> + * + * Original Distortion algorithms copyrighted 2004-2005 by + * Pieter Z. Voloshyn <pieter dot voloshyn at gmail dot com>. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * ============================================================ */ + +#ifndef DISTORTIONFXTOOL_H +#define DISTORTIONFXTOOL_H + +// Digikam includes. + +#include "editortool.h" + +class TQLabel; + +namespace KDcrawIface +{ +class RIntNumInput; +class RComboBox; +} + +namespace Digikam +{ +class ImageWidget; +} + +namespace DigikamDistortionFXImagesPlugin +{ + +class DistortionFXTool : public Digikam::EditorToolThreaded +{ +    TQ_OBJECT +   + +public: + +    DistortionFXTool(TQObject *parent); +    ~DistortionFXTool(); + +private slots: + +    void slotEffectTypeChanged(int type); +    void slotResetSettings(); +    void slotColorGuideChanged(); + +private: + +    void readSettings(); +    void writeSettings(); +    void prepareEffect(); +    void prepareFinal(); +    void putPreviewData(); +    void putFinalData(); +    void renderingFinished(); + +private: + + +    TQLabel                      *m_effectTypeLabel; +    TQLabel                      *m_levelLabel; +    TQLabel                      *m_iterationLabel; + +    KDcrawIface::RComboBox      *m_effectType; + +    KDcrawIface::RIntNumInput   *m_levelInput; +    KDcrawIface::RIntNumInput   *m_iterationInput; + +    Digikam::ImageWidget        *m_previewWidget; + +    Digikam::EditorToolSettings *m_gboxSettings; +}; + +}  // NameSpace DigikamDistortionFXImagesPlugin + +#endif /* DISTORTIONFXTOOL_H */ diff --git a/src/imageplugins/distortionfx/imageeffect_distortionfx.cpp b/src/imageplugins/distortionfx/imageeffect_distortionfx.cpp new file mode 100644 index 00000000..695e7749 --- /dev/null +++ b/src/imageplugins/distortionfx/imageeffect_distortionfx.cpp @@ -0,0 +1,378 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date        : 2005-02-11 + * Description : a plugin to apply Distortion FX to an image. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * Copyright (C) 2006-2008 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> + * + * Original Distortion algorithms copyrighted 2004-2005 by  + * Pieter Z. Voloshyn <pieter dot voloshyn at gmail dot com>. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) + * any later version. + *  + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + *  + * ============================================================ */  + +// TQt includes.  +  +#include <tqlabel.h> +#include <tqwhatsthis.h> +#include <tqlayout.h> +#include <tqframe.h> +#include <tqimage.h> +#include <tqspinbox.h> +#include <tqcombobox.h> + +// KDE includes. + +#include <tdeconfig.h> +#include <tdelocale.h> +#include <kcursor.h> +#include <tdeaboutdata.h> +#include <khelpmenu.h> +#include <tdeapplication.h> +#include <knuminput.h> +#include <kstandarddirs.h> +#include <kprogress.h> + +// Local includes. + +#include "version.h" +#include "ddebug.h" +#include "dimg.h" +#include "imageiface.h" +#include "imagewidget.h" +#include "distortionfx.h" +#include "imageeffect_distortionfx.h" +#include "imageeffect_distortionfx.moc" + +namespace DigikamDistortionFXImagesPlugin +{ + +ImageEffect_DistortionFX::ImageEffect_DistortionFX(TQWidget* parent) +                        : Digikam::ImageGuideDlg(parent, i18n("Distortion Effects"), +                                                 "distortionfx", false, true, false, +                                                 Digikam::ImageGuideWidget::HVGuideMode) +{ +    // About data and help button. +     +    TDEAboutData* about = new TDEAboutData("digikam", +                                       I18N_NOOP("Distortion Effects"),  +                                       digikam_version, +                                       I18N_NOOP("A digiKam image plugin to apply distortion effects to an image."), +                                       TDEAboutData::License_GPL, +                                       "(c) 2005, Gilles Caulier\n" +                                       "(c) 2006-2008, Gilles Caulier and Marcel Wiesweg",  +                                       0, +                                       "http://www.digikam.org"); +                                        +    about->addAuthor("Gilles Caulier", I18N_NOOP("Author and maintainer"), +                     "caulier dot gilles at gmail dot com"); + +    about->addAuthor("Pieter Z. Voloshyn", I18N_NOOP("Distortion algorithms"),  +                     "pieter dot voloshyn at gmail dot com");  + +    about->addAuthor("Marcel Wiesweg", I18N_NOOP("Developer"), +                     "marcel dot wiesweg at gmx dot de"); + +    setAboutData(about); +         +    TQWhatsThis::add( m_imagePreviewWidget, i18n("<p>This is the preview of the distortion effect " +                                                "applied to the photograph.") ); +                                            +    // ------------------------------------------------------------- +     +    TQWidget *gboxSettings = new TQWidget(plainPage()); +    TQGridLayout* gridSettings = new TQGridLayout( gboxSettings, 5, 2, spacingHint()); +     +    m_effectTypeLabel = new TQLabel(i18n("Type:"), gboxSettings); +     +    m_effectType = new TQComboBox( false, gboxSettings ); +    m_effectType->insertItem( i18n("Fish Eyes") ); +    m_effectType->insertItem( i18n("Twirl") ); +    m_effectType->insertItem( i18n("Cylindrical Hor.") ); +    m_effectType->insertItem( i18n("Cylindrical Vert.") ); +    m_effectType->insertItem( i18n("Cylindrical H/V.") ); +    m_effectType->insertItem( i18n("Caricature") ); +    m_effectType->insertItem( i18n("Multiple Corners") ); +    m_effectType->insertItem( i18n("Waves Hor.") ); +    m_effectType->insertItem( i18n("Waves Vert.") ); +    m_effectType->insertItem( i18n("Block Waves 1") ); +    m_effectType->insertItem( i18n("Block Waves 2") ); +    m_effectType->insertItem( i18n("Circular Waves 1") ); +    m_effectType->insertItem( i18n("Circular Waves 2") ); +    m_effectType->insertItem( i18n("Polar Coordinates") );     +    m_effectType->insertItem( i18n("Unpolar Coordinates") );     +    m_effectType->insertItem( i18n("Tile") );     +    TQWhatsThis::add( m_effectType, i18n("<p>Here, select the type of effect to apply to the image.<p>" +                                        "<b>Fish Eyes</b>: warps the photograph around a 3D spherical shape to " +                                        "reproduce the common photograph 'Fish Eyes' effect.<p>" +                                        "<b>Twirl</b>: spins the photograph to produce a Twirl pattern.<p>" +                                        "<b>Cylinder Hor.</b>: warps the photograph around a horizontal cylinder.<p>" +                                        "<b>Cylinder Vert.</b>: warps the photograph around a vertical cylinder.<p>" +                                        "<b>Cylinder H/V.</b>: warps the photograph around 2 cylinders, vertical " +                                        "and horizontal.<p>" +                                        "<b>Caricature</b>: distorts the photograph with the 'Fish Eyes' effect inverted.<p>" +                                        "<b>Multiple Corners</b>: splits the photograph like a multiple corners pattern.<p>" +                                        "<b>WavesQt Horizontal</b>: distorts the photograph with horizontal waves.<p>" +                                        "<b>Waves Vertical</b>: distorts the photograph with vertical waves.<p>" +                                        "<b>Block Waves 1</b>: divides the image into cells and makes it look as " +                                        "if it is being viewed through glass blocks.<p>" +                                        "<b>Block Waves 2</b>: like Block Waves 1 but with another version " +                                        "of glass blocks distortion.<p>" +                                        "<b>Circular Waves 1</b>: distorts the photograph with circular waves.<p>" +                                        "<b>Circular Waves 2</b>: another variation of the Circular Waves effect.<p>" +                                        "<b>Polar Coordinates</b>: converts the photograph from rectangular " +                                        "to polar coordinates.<p>" +                                        "<b>Unpolar Coordinates</b>: the Polar Coordinates effect inverted.<p>" +                                        "<b>Tile</b>: splits the photograph into square blocks and moves " +                                        "them randomly inside the image.<p>" +                                        )); +    gridSettings->addMultiCellWidget(m_effectTypeLabel, 0, 0, 0, 2); +    gridSettings->addMultiCellWidget(m_effectType, 1, 1, 0, 2); +                                                   +    m_levelLabel = new TQLabel(i18n("Level:"), gboxSettings); +    m_levelInput = new KIntNumInput(gboxSettings); +    m_levelInput->setRange(0, 100, 1, true); +    TQWhatsThis::add( m_levelInput, i18n("<p>Set here the level of the effect.")); +     +    gridSettings->addMultiCellWidget(m_levelLabel, 2, 2, 0, 2); +    gridSettings->addMultiCellWidget(m_levelInput, 3, 3, 0, 2); +         +    m_iterationLabel = new TQLabel(i18n("Iteration:"), gboxSettings); +    m_iterationInput = new KIntNumInput(gboxSettings); +    m_iterationInput->setRange(0, 100, 1, true); +    TQWhatsThis::add( m_iterationInput, i18n("<p>This value controls the iterations to use for Waves, " +                                            "Tile, and Neon effects.")); +     +    gridSettings->addMultiCellWidget(m_iterationLabel, 4, 4, 0, 2); +    gridSettings->addMultiCellWidget(m_iterationInput, 5, 5, 0, 2); +     +    setUserAreaWidget(gboxSettings);  + +    // ------------------------------------------------------------- +     +    connect(m_effectType, TQ_SIGNAL(activated(int)), +            this, TQ_SLOT(slotEffectTypeChanged(int))); +     +    connect(m_levelInput, TQ_SIGNAL(valueChanged(int)), +            this, TQ_SLOT(slotTimer()));             +             +    connect(m_iterationInput, TQ_SIGNAL(valueChanged(int)), +            this, TQ_SLOT(slotTimer()));             +} + +ImageEffect_DistortionFX::~ImageEffect_DistortionFX() +{ +} + +void ImageEffect_DistortionFX::renderingFinished() +{ +    m_effectTypeLabel->setEnabled(true); +    m_effectType->setEnabled(true); +    m_levelInput->setEnabled(true); +    m_levelLabel->setEnabled(true); +    m_iterationInput->setEnabled(true); +    m_iterationLabel->setEnabled(true); + +    switch (m_effectType->currentItem()) +       { +       case DistortionFX::FishEye: +       case DistortionFX::Twirl:  +       case DistortionFX::CilindricalHor:   +       case DistortionFX::CilindricalVert:   +       case DistortionFX::CilindricalHV:   +       case DistortionFX::Caricature:  +       case DistortionFX::MultipleCorners:            +          break; +        +       case DistortionFX::PolarCoordinates:  +       case DistortionFX::UnpolarCoordinates:  +          m_levelInput->setEnabled(false); +          m_levelLabel->setEnabled(false); +          break; + +       case DistortionFX::WavesHorizontal:  +       case DistortionFX::WavesVertical:   +       case DistortionFX::BlockWaves1:   +       case DistortionFX::BlockWaves2:  +       case DistortionFX::CircularWaves1:  +       case DistortionFX::CircularWaves2:  +       case DistortionFX::Tile:  +          m_iterationInput->setEnabled(true); +          m_iterationLabel->setEnabled(true); +          break; +       } +} + +void ImageEffect_DistortionFX::readUserSettings(void) +{ +    TDEConfig *config = kapp->config(); +    config->setGroup("distortionfx Tool Dialog"); + +    m_effectType->blockSignals(true); +    m_iterationInput->blockSignals(true); +    m_levelInput->blockSignals(true); + +    m_effectType->setCurrentItem(config->readNumEntry("EffectType", DistortionFX::FishEye)); +    m_iterationInput->setValue(config->readNumEntry("IterationAjustment", 10)); +    m_levelInput->setValue(config->readNumEntry("LevelAjustment", 50)); + +    m_effectType->blockSignals(false); +    m_iterationInput->blockSignals(false); +    m_levelInput->blockSignals(false); + +    slotEffect(); +} + +void ImageEffect_DistortionFX::writeUserSettings(void) +{ +    TDEConfig *config = kapp->config(); +    config->setGroup("distortionfx Tool Dialog"); +    config->writeEntry("EffectType", m_effectType->currentItem()); +    config->writeEntry("IterationAjustment", m_iterationInput->value()); +    config->writeEntry("LevelAjustment", m_levelInput->value()); +    config->sync(); +} + +void ImageEffect_DistortionFX::resetValues() +{ +    m_effectType->blockSignals(true); +    m_effectType->setCurrentItem(DistortionFX::FishEye); +    slotEffectTypeChanged(DistortionFX::FishEye); +    m_effectType->blockSignals(false); +}  + +void ImageEffect_DistortionFX::slotEffectTypeChanged(int type) +{ +    m_levelInput->setEnabled(true); +    m_levelLabel->setEnabled(true); +     +    m_levelInput->blockSignals(true); +    m_iterationInput->blockSignals(true); +    m_levelInput->setRange(0, 100, 1, true); +    m_levelInput->setValue(25); +           +    switch (type) +       { +       case DistortionFX::Twirl:  +          m_levelInput->setRange(-50, 50, 1, true); +          m_levelInput->setValue(10); +          break; + +       case DistortionFX::FishEye:  +       case DistortionFX::CilindricalHor:   +       case DistortionFX::CilindricalVert:   +       case DistortionFX::CilindricalHV:   +       case DistortionFX::Caricature:   +          m_levelInput->setRange(0, 200, 1, true); +          m_levelInput->setValue(50); +          break; + +       case DistortionFX::MultipleCorners:  +          m_levelInput->setRange(1, 10, 1, true); +          m_levelInput->setValue(4); +          break; +                                                   +       case DistortionFX::WavesHorizontal:  +       case DistortionFX::WavesVertical:   +       case DistortionFX::BlockWaves1:  +       case DistortionFX::BlockWaves2:  +       case DistortionFX::CircularWaves1:  +       case DistortionFX::CircularWaves2:  +       case DistortionFX::Tile:  +          m_iterationInput->setEnabled(true); +          m_iterationLabel->setEnabled(true); +          m_iterationInput->setRange(0, 200, 1, true); +          m_iterationInput->setValue(10); +          break; + +       case DistortionFX::PolarCoordinates: +       case DistortionFX::UnpolarCoordinates:  +          m_levelInput->setEnabled(false); +          m_levelLabel->setEnabled(false); +          break; +       } + +    m_levelInput->blockSignals(false); +    m_iterationInput->blockSignals(false); +        +    slotEffect(); +} + +void ImageEffect_DistortionFX::prepareEffect() +{ +    m_effectTypeLabel->setEnabled(false); +    m_effectType->setEnabled(false); +    m_levelInput->setEnabled(false); +    m_levelLabel->setEnabled(false); +    m_iterationInput->setEnabled(false); +    m_iterationLabel->setEnabled(false); + +    int l = m_levelInput->value(); +    int f = m_iterationInput->value(); +    int e = m_effectType->currentItem(); + +    Digikam::ImageIface* iface = m_imagePreviewWidget->imageIface(); + +    uchar *data = iface->getPreviewImage(); +    Digikam::DImg image(iface->previewWidth(), iface->previewHeight(), iface->previewSixteenBit(), +                        iface->previewHasAlpha(), data); +    delete [] data; + +    m_threadedFilter = dynamic_cast<Digikam::DImgThreadedFilter *>( +                       new DistortionFX(&image, this, e, l, f)); +} + +void ImageEffect_DistortionFX::prepareFinal() +{ +    m_effectTypeLabel->setEnabled(false); +    m_effectType->setEnabled(false); +    m_levelInput->setEnabled(false); +    m_levelLabel->setEnabled(false); +    m_iterationInput->setEnabled(false); +    m_iterationLabel->setEnabled(false); + +    int l = m_levelInput->value(); +    int f = m_iterationInput->value(); +    int e = m_effectType->currentItem(); + +    Digikam::ImageIface iface(0, 0); + +    m_threadedFilter = dynamic_cast<Digikam::DImgThreadedFilter *>( +                       new DistortionFX(iface.getOriginalImg(), this, e, l, f)); +} + +void ImageEffect_DistortionFX::putPreviewData(void) +{ +    Digikam::ImageIface* iface = m_imagePreviewWidget->imageIface(); + +    Digikam::DImg imDest = m_threadedFilter->getTargetImage() +            .smoothScale(iface->previewWidth(), iface->previewHeight()); +    iface->putPreviewImage(imDest.bits()); + +    m_imagePreviewWidget->updatePreview(); +} + +void ImageEffect_DistortionFX::putFinalData(void) +{ +    Digikam::ImageIface iface(0, 0); + +    iface.putOriginalImage(i18n("Distortion Effects"),  +                           m_threadedFilter->getTargetImage().bits()); +} + +}  // NameSpace DigikamDistortionFXImagesPlugin + diff --git a/src/imageplugins/distortionfx/imageeffect_distortionfx.h b/src/imageplugins/distortionfx/imageeffect_distortionfx.h new file mode 100644 index 00000000..652b372b --- /dev/null +++ b/src/imageplugins/distortionfx/imageeffect_distortionfx.h @@ -0,0 +1,82 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date        : 2005-02-11 + * Description : a plugin to apply Distortion FX to an image. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * Copyright (C) 2006-2008 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> + * + * Original Distortion algorithms copyrighted 2004-2005 by  + * Pieter Z. Voloshyn <pieter dot voloshyn at gmail dot com>. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) + * any later version. + *  + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + *  + * ============================================================ */  + +#ifndef IMAGEEFFECT_DISTORTIONFX_H +#define IMAGEEFFECT_DISTORTIONFX_H + +// Digikam includes. + +#include "imageguidedlg.h" + +class TQComboBox; +class TQLabel; + +class KIntNumInput; + +namespace DigikamDistortionFXImagesPlugin +{ + +class ImageEffect_DistortionFX : public Digikam::ImageGuideDlg +{ +    TQ_OBJECT +   +     +public: + +    ImageEffect_DistortionFX(TQWidget *parent); +    ~ImageEffect_DistortionFX(); + +private slots: + +    void slotEffectTypeChanged(int type); +    void readUserSettings(); + +private: + +    void writeUserSettings(); +    void resetValues();   +    void prepareEffect(); +    void prepareFinal(); +    void putPreviewData(); +    void putFinalData(); +    void renderingFinished();     + +private: +     +    TQComboBox            *m_effectType; + +    TQLabel               *m_effectTypeLabel; +    TQLabel               *m_levelLabel; +    TQLabel               *m_iterationLabel; +     +    KIntNumInput         *m_levelInput; +    KIntNumInput         *m_iterationInput; +}; + +}  // NameSpace DigikamDistortionFXImagesPlugin + +#endif /* IMAGEEFFECT_DISTORTIONFX_H */ diff --git a/src/imageplugins/distortionfx/imageplugin_distortionfx.cpp b/src/imageplugins/distortionfx/imageplugin_distortionfx.cpp new file mode 100644 index 00000000..582e1b99 --- /dev/null +++ b/src/imageplugins/distortionfx/imageplugin_distortionfx.cpp @@ -0,0 +1,72 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date        : 2005-02-11 + * Description : a plugin to apply Distortion FX to an image. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * Original Distortion algorithms copyrighted 2004-2005 by + * Pieter Z. Voloshyn <pieter dot voloshyn at gmail dot com>. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * ============================================================ */ + +// KDE includes. + +#include <tdelocale.h> +#include <kgenericfactory.h> +#include <klibloader.h> +#include <tdeaction.h> +#include <kcursor.h> + +// Local includes. + +#include "ddebug.h" +#include "distortionfxtool.h" +#include "imageplugin_distortionfx.h" +#include "imageplugin_distortionfx.moc" + +using namespace DigikamDistortionFXImagesPlugin; + +K_EXPORT_COMPONENT_FACTORY(digikamimageplugin_distortionfx, +                           KGenericFactory<ImagePlugin_DistortionFX>("digikamimageplugin_distortionfx")); + +ImagePlugin_DistortionFX::ImagePlugin_DistortionFX(TQObject *parent, const char*, const TQStringList &) +                        : Digikam::ImagePlugin(parent, "ImagePlugin_DistortionFX") +{ +    m_distortionfxAction = new TDEAction(i18n("Distortion Effects..."), "distortionfx", 0, +                               this, TQ_SLOT(slotDistortionFX()), +                               actionCollection(), "imageplugin_distortionfx"); + +    setXMLFile( "digikamimageplugin_distortionfx_ui.rc" ); + +    DDebug() << "ImagePlugin_DistortionFX plugin loaded" << endl; +} + +ImagePlugin_DistortionFX::~ImagePlugin_DistortionFX() +{ +} + +void ImagePlugin_DistortionFX::setEnabledActions(bool enable) +{ +    m_distortionfxAction->setEnabled(enable); +} + +void ImagePlugin_DistortionFX::slotDistortionFX() +{ +    DistortionFXTool *distortionfx = new DistortionFXTool(this); +    loadTool(distortionfx); +} diff --git a/src/imageplugins/distortionfx/imageplugin_distortionfx.h b/src/imageplugins/distortionfx/imageplugin_distortionfx.h new file mode 100644 index 00000000..2af33a14 --- /dev/null +++ b/src/imageplugins/distortionfx/imageplugin_distortionfx.h @@ -0,0 +1,59 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date        : 2005-02-11 + * Description : a plugin to apply Distortion FX to an image. + * + * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * Original Distortion algorithms copyrighted 2004-2005 by  + * Pieter Z. Voloshyn <pieter dot voloshyn at gmail dot com>. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) + * any later version. + *  + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + *  + * ============================================================ */  + +#ifndef IMAGEPLUGIN_DISTORTIONFX_H +#define IMAGEPLUGIN_DISTORTIONFX_H + +// Digikam includes. + +#include "imageplugin.h" +#include "digikam_export.h" + +class TDEAction; + +class DIGIKAMIMAGEPLUGINS_EXPORT ImagePlugin_DistortionFX : public Digikam::ImagePlugin +{ +    TQ_OBJECT +   +     +public: + +    ImagePlugin_DistortionFX(TQObject *parent, const char* name, +                             const TQStringList &args); +    ~ImagePlugin_DistortionFX(); + +    void setEnabledActions(bool enable); + +private slots: + +    void slotDistortionFX(); + +private: + +    TDEAction *m_distortionfxAction; +}; +     +#endif /* IMAGEPLUGIN_DISTORTIONFX_H */ | 
