/* ============================================================ * * 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 * Copyright (C) 2006-2008 by Marcel Wiesweg * * Original Distortion algorithms copyrighted 2004-2005 by * Pieter Z. Voloshyn . * * 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 #include #include #include #include #include // KDE includes. #include #include #include #include #include #include #include #include #include // LibKDcraw includes. #include #include // 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("

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("

Here, select the type of effect to apply to the image.

" "Fish Eyes: warps the photograph around a 3D spherical shape to " "reproduce the common photograph 'Fish Eyes' effect.

" "Twirl: spins the photograph to produce a Twirl pattern.

" "Cylinder Hor.: warps the photograph around a horizontal cylinder.

" "Cylinder Vert.: warps the photograph around a vertical cylinder.

" "Cylinder H/V.: warps the photograph around 2 cylinders, vertical " "and horizontal.

" "Caricature: distorts the photograph with the 'Fish Eyes' effect inverted.

" "Multiple Corners: splits the photograph like a multiple corners pattern.

" "Waves Horizontal: distorts the photograph with horizontal waves.

" "Waves Vertical: distorts the photograph with vertical waves.

" "Block Waves 1: divides the image into cells and makes it look as " "if it is being viewed through glass blocks.

" "Block Waves 2: like Block Waves 1 but with another version " "of glass blocks distortion.

" "Circular Waves 1: distorts the photograph with circular waves.

" "Circular Waves 2: another variation of the Circular Waves effect.

" "Polar Coordinates: converts the photograph from rectangular " "to polar coordinates.

" "Unpolar Coordinates: the Polar Coordinates effect inverted.

" "Tile: splits the photograph into square blocks and moves " "them randomly inside the image.

" )); 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("

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("

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, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotEffectTypeChanged(int))); connect(m_levelInput, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotTimer())); connect(m_iterationInput, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotTimer())); connect(m_gboxSettings, TQT_SIGNAL(signalColorGuideChanged()), this, TQT_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 (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 (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