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-5bed6e4a4c916a97f8fe4d1b07f7eecf4d733b90.tar.gz digikam-5bed6e4a4c916a97f8fe4d1b07f7eecf4d733b90.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 */ |