grainEditor.cpp

Go to the documentation of this file.
00001 //==============================================
00002 //  copyright            : (C) 2003-2005 by Will Stokes
00003 //==============================================
00004 //  This program is free software; you can redistribute it
00005 //  and/or modify it under the terms of the GNU General
00006 //  Public License as published by the Free Software
00007 //  Foundation; either version 2 of the License, or
00008 //  (at your option) any later version.
00009 //==============================================
00010 
00011 //Systemwide includes
00012 #include <qlayout.h>
00013 #include <qlabel.h>
00014 #include <qcombobox.h>
00015 #include <qpushbutton.h>
00016 #include <qframe.h>
00017 #include <qslider.h>
00018 #include <qtooltip.h>
00019 #include <qsizegrip.h>
00020 
00021 //Projectwide includes
00022 #include "grainEditor.h"
00023 #include "panningPreviewInterface.h"
00024 #include "selectionPlacementInterface.h"
00025 #include "../blurSharpenSlider.h"
00026 #include "../clickableLabel.h"
00027 #include "../../config.h"
00028 #include "../../backend/manipulations/blur.h"
00029 #include "../../backend/manipulations/sharpen.h"
00030 #include "../../backend/manipulations/edgeDetect.h"
00031 #include "../../backend/tools/imageTools.h"
00032 
00033 #define SLIDER_RADIUS 50
00034 
00035 //==============================================
00036 GrainEditor::GrainEditor( QString fileName, QWidget *parent, const char* name ) : QDialog(parent,name,true)
00037 {
00038   //record filename
00039   this->fileName = fileName;
00040 
00041   //record original image size
00042   getImageSize( fileName, origImageSize );
00043   
00044   //construct edges image
00045   //speed up edge finding by scaling image down to < 800x600
00046   scaleImage( fileName, edgesImage, 512, 384 );
00047   EdgeDetect detector( &edgesImage );
00048   clusterMap = detector.getClusterMap();
00049   numRegions = detector.getNumClusters();
00050   
00051   QFrame* visibleFrame = new QFrame( this, "visible widgets" );
00052   //--------------
00053   //Preview frame
00054   previewInterface = new PanningPreviewInterface( fileName, 
00055                                                   visibleFrame, "previewInterface" );
00056   previewSelection = new QComboBox( visibleFrame, "previewSelction" );
00057   previewSelection->insertItem( tr("Split View") );
00058   previewSelection->insertItem( tr("Original Image") );
00059   previewSelection->insertItem( tr("Adjusted Image") );
00060   connect( previewSelection, SIGNAL(activated(int)), this, SLOT(selectPreviewImageType(int)) );  
00061    //--------------  
00062   //Controls frame 
00063   QFrame* controlsFrame = new QFrame( visibleFrame, "controlsFrame" );
00064 
00065   QLabel* selectionLabel = new QLabel( tr("Region Shown in Detail:"), 
00066                                        controlsFrame, "selectionLabel" );
00067   
00068   selectionPlacementInterface = new SelectionPlacementInterface( fileName, 
00069                                                                  controlsFrame, 
00070                                                                  "selectionPlacementInterface" );
00071   //--
00072   connect( previewInterface, SIGNAL( selectionChanged() ),
00073            this, SLOT( previewResized() ) );
00074   connect( selectionPlacementInterface, SIGNAL(placementChanged(QRect)), 
00075            previewInterface, SLOT(setSelection(QRect)) );  
00076   //--
00077   boundariesSlider = new BlurSharpenSlider( Qt::Vertical, controlsFrame );
00078   boundariesSlider->setMinValue( -SLIDER_RADIUS );
00079   boundariesSlider->setMaxValue( SLIDER_RADIUS );
00080   connect( boundariesSlider, SIGNAL(valueChanged(int)),
00081            this, SLOT(generateAdjustedPreviewImage()) );
00082            
00083   boundariesIcon = new ClickableLabel( controlsFrame, "boundariesIcon" );
00084   connect( boundariesIcon, SIGNAL(clicked()), SLOT(resetBoundaries()) );    
00085 
00086 //  boundariesIcon->setPixmap( QPixmap(QString(IMAGE_PATH)+"miscImages/boundaries.png") );
00087 //  QToolTip::add( boundariesSlider, tr("Blur/sharpen boundaries") );  
00088 //  QToolTip::add( boundariesIcon, tr("Reset boundaries") );
00089   boundariesIcon->setPixmap( QPixmap(QString(IMAGE_PATH)+"miscImages/blurSharpen.png") );
00090   QToolTip::add( boundariesSlider, tr("Blur/Sharpen Image") );  
00091   QToolTip::add( boundariesIcon, tr("Reset") );
00092   //--
00093   /*
00094  regionsSlider = new QSlider(Qt::Vertical, controlsFrame );
00095   regionsSlider->setMinValue( -SLIDER_RADIUS );
00096   regionsSlider->setMaxValue( SLIDER_RADIUS );
00097   connect( regionsSlider, SIGNAL(valueChanged(int)),
00098            this, SLOT(generateAdjustedPreviewImage()) );
00099   QToolTip::add( regionsSlider, tr("Blur/sharpen regions") );  
00100   
00101   regionsIcon = new ClickableLabel( controlsFrame, "regionsIcon" );
00102   regionsIcon->setPixmap( QPixmap(QString(IMAGE_PATH)+"miscImages/regions.png") );
00103   connect( regionsIcon, SIGNAL(clicked()), SLOT(resetRegions()) );    
00104   QToolTip::add( regionsIcon, tr("Reset regions") );
00105  */
00106   //--
00107   QGridLayout* controlsGrid = new QGridLayout( controlsFrame, 6, 4, 0 );
00108   controlsGrid->setRowStretch( 0, 1 );  
00109 
00110   controlsGrid->addMultiCellWidget( selectionLabel,              1,1, 0,3 );
00111   controlsGrid->addMultiCellWidget( selectionPlacementInterface, 2,2, 0,3 );
00112 
00113   controlsGrid->addWidget( boundariesSlider,  3, 1 );
00114   controlsGrid->addWidget( boundariesIcon,    4, 1 );
00115 
00116 //  controlsGrid->addWidget( regionsSlider,  3, 2 );
00117 //  controlsGrid->addWidget( regionsIcon,    4, 2 );
00118 
00119   //make sure sliders have enough space so all slider units are settable
00120   controlsGrid->setRowSpacing( 3, 2*SLIDER_RADIUS + 5) ;
00121  
00122   controlsGrid->setRowStretch( 5, 1 );  
00123   controlsGrid->setSpacing( WIDGET_SPACING ); 
00124 
00125   controlsGrid->setColStretch( 0, 1 );
00126   controlsGrid->setColStretch( 3, 1 );
00127   //--------------
00128   //Dialog buttons:  
00129   buttonsFrame =   new QFrame( visibleFrame, "dialogButtons" );
00130 
00131   QPushButton* applyButton = new QPushButton( tr("Apply"), buttonsFrame );
00132   applyButton->setDefault(true);
00133   applyButton->setFocus();
00134   connect( applyButton, SIGNAL(clicked()), SLOT(applyAction()) );
00135                                 
00136   QPushButton* cancelButton = new QPushButton( tr("Cancel"), buttonsFrame );
00137   connect( cancelButton, SIGNAL(clicked()), SLOT(reject()) );
00138 
00139   QPushButton* resetButton = new QPushButton( tr("Reset"), buttonsFrame );
00140   connect( resetButton, SIGNAL(clicked()), SLOT(resetAction()) );
00141 
00142   QGridLayout* buttonsGrid = new QGridLayout( buttonsFrame, 1, 5, 0 );
00143   buttonsGrid->setColStretch( 0, 1 );
00144   buttonsGrid->addWidget( applyButton,  0, 1 );
00145   buttonsGrid->addWidget( cancelButton, 0, 2 );
00146   buttonsGrid->addWidget( resetButton, 0, 3 );
00147   buttonsGrid->setColStretch( 4, 1 );  
00148   buttonsGrid->setSpacing( WIDGET_SPACING );
00149   //--------------
00150   //Top level grid  
00151   QGridLayout* mainGrid = new QGridLayout( visibleFrame, 3, 2, 0 );
00152   
00153   mainGrid->addWidget( previewInterface, 0,0 );
00154   mainGrid->addWidget( previewSelection, 1,0, Qt::AlignHCenter );  
00155 
00156   mainGrid->addMultiCellWidget( controlsFrame, 0,1, 1,1 );
00157   
00158   mainGrid->addMultiCellWidget( buttonsFrame, 2,2, 0,1 );
00159 
00160   mainGrid->setRowStretch( 0, 1 );
00161   mainGrid->setColStretch( 0, 1 );
00162 
00163   mainGrid->setSpacing( WIDGET_SPACING );
00164   mainGrid->setMargin( WIDGET_SPACING );  
00165 
00166 
00167   QGridLayout* invisibleGrid = new QGridLayout( this, 2, 1, 0 );
00168   invisibleGrid->addWidget( visibleFrame, 0, 0 );
00169   invisibleGrid->setRowStretch( 0, 1 );
00170 
00171   //PLATFORM_SPECIFIC_CODE
00172   //windows users expect a grip, but qt doesn't put one in by default. we'll add
00173   //it for them too. :-)
00174 #if defined(Q_OS_WIN)
00175   QSizeGrip* sizeGrip = new QSizeGrip( this );
00176   invisibleGrid->addWidget( sizeGrip, 1, 0, Qt::AlignRight | Qt::AlignBottom );
00177 #endif
00178   
00179   
00180   
00181   
00182   //--------------
00183   //Window caption
00184   setCaption( tr("Grain Editor") );
00185   //-------------------------------
00186 }
00187 //==============================================
00188 GrainEditor::~GrainEditor() { }
00189 //==============================================
00190 void GrainEditor::applyAction()
00191 {
00192   //check if user has adjusted grain.
00193   //if any changes have taken place call "accept", else "reject" so image is not
00194   //updated and appear modified
00195   if( boundariesSlider->value() != 0 )
00196     //||
00197     //  regionsSlider->value() != 0 )
00198   { accept(); }
00199   else
00200   { reject(); }  
00201 }
00202 //==============================================
00203 void GrainEditor::resetBoundaries()
00204 {
00205   boundariesSlider->setValue( 0 );
00206 }
00207 //==============================================
00208 void GrainEditor::resetRegions()
00209 {
00210   //regionsSlider->setValue( 0 );
00211 }
00212 //==============================================
00213 void GrainEditor::resetAction()
00214 {
00215   boundariesSlider->setValue( 0 );
00216   //regionsSlider->setValue( 0 );
00217 }
00218 //==============================================
00219 QImage* GrainEditor::getModifiedImage()
00220 { 
00221   QImage* adjustedImage = new QImage(fileName);  
00222 
00223   //convert to 32-bit depth if necessary
00224   if( adjustedImage->depth() < 32 )
00225   {
00226     QImage* tmp = adjustedImage;
00227     adjustedImage = new QImage( tmp->convertDepth( 32, Qt::AutoColor ) );
00228     delete tmp; tmp=NULL;
00229   }
00230   
00231   adjustImage( *adjustedImage, QPoint(0,0) );
00232   return adjustedImage;  
00233 }
00234 //==============================================
00235 void GrainEditor::selectPreviewImageType( int selection )
00236 {
00237   previewInterface->setPreviewMode( (PREVIEW_MODE)selection );
00238 }
00239 //==============================================
00240 void GrainEditor::previewResized()
00241 {
00242   //reset selected region in selection placement interface
00243   selectionPlacementInterface->setSelectedRegion( previewInterface->getSelection() );
00244 
00245   //regenerate adjusted image and repaint
00246   generateAdjustedPreviewImage();
00247 }
00248 //==============================================
00249 void GrainEditor::generateAdjustedPreviewImage()
00250 {
00251   //get original image
00252   QImage origImage = previewInterface->getOrigImage();
00253 
00254   //construct adjusted image
00255   QImage adjustedImage = origImage.copy();
00256   adjustImage( adjustedImage, previewInterface->getSelection().topLeft() );
00257   
00258   //set adjusted image
00259   previewInterface->setAdjustedImage( adjustedImage );
00260 }
00261 //==============================================
00262 void GrainEditor::adjustImage( QImage& image, QPoint offset )
00263 {
00264   //no adjustment - don't change the image at all
00265   if( boundariesSlider->value() == 0 )//&&
00266       //regionsSlider->value() == 0 )
00267   { return; }
00268   
00269   //compute sigma
00270   float boundariesSigma;
00271   if( boundariesSlider->value() < 0 )
00272     boundariesSigma = (80.0f * QABS(boundariesSlider->value()) ) / 255.0f;  
00273   else
00274     boundariesSigma = (25.5f * QABS(boundariesSlider->value()) ) / 255.0f;  
00275 //  float regionsSigma = (20.0f * QABS(regionsSlider->value()) ) / 255.0f;  
00276 
00277   
00278   //sharpen
00279   if ( boundariesSlider->value() < 0 )
00280   {
00281     sharpenImage( image, boundariesSigma, 
00282                   offset, origImageSize,
00283                   &edgesImage, true ); 
00284   }
00285   //blur
00286   else if( boundariesSlider->value() > 0 )
00287   {
00288     blurImage( image, boundariesSigma );
00289   }
00290 
00291   /*
00292   //sharpen boundaries
00293   if ( boundariesSlider->value() < 0 )
00294   {
00295     sharpenImage( image, boundariesSigma, 
00296                   offset, origImageSize,
00297                   &edgesImage, true ); 
00298   }
00299   //blur boundaries
00300   else if( boundariesSlider->value() > 0 )
00301   {
00302     blurImage( image, boundariesSigma, 
00303                offset, origImageSize,
00304                &edgesImage, NULL, numRegions, true ); 
00305   }
00306   
00307   //sharpen regions
00308   if ( regionsSlider->value() < 0 )
00309   {
00310     sharpenImage( image, regionsSigma, 
00311                   offset, origImageSize,
00312                   &edgesImage, false ); 
00313   }
00314   //blur regions
00315   else if( regionsSlider->value() > 0 )
00316   { 
00317     blurImage( image, regionsSigma, 
00318                offset, origImageSize,
00319                &edgesImage, clusterMap, numRegions, false );
00320   }
00321   */
00322 
00323 }
00324 //==============================================
00325 void GrainEditor::keyPressEvent(QKeyEvent *e)
00326 {
00327   if(e->key() == Qt::Key_Control )
00328   {
00329     PREVIEW_MODE curMode = (PREVIEW_MODE) previewSelection->currentItem();
00330     if(curMode == ORIGINAL_IMAGE)
00331       previewInterface->setPreviewMode( ADJUSTED_IMAGE, true );
00332     else if(curMode == ADJUSTED_IMAGE)
00333       previewInterface->setPreviewMode( ORIGINAL_IMAGE, true );
00334     else
00335       previewInterface->setPreviewMode( INV_SPLIT_VIEW );
00336   }
00337   else { QDialog::keyPressEvent(e); }
00338 }
00339 //==============================================
00340 void GrainEditor::keyReleaseEvent(QKeyEvent *e)
00341 {
00342   if(e->key() == Qt::Key_Control )
00343   {
00344     previewInterface->setPreviewMode( (PREVIEW_MODE) previewSelection->currentItem(), 
00345                                       false );
00346   }
00347   else { QDialog::keyReleaseEvent(e); }
00348 }
00349 //==============================================
00350 
00351 
00352 

Generated on Wed Jan 24 05:38:28 2007 for AlbumShaper by  doxygen 1.5.1