Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

HistogramEditor Class Reference

#include <histogramEditor.h>

Inheritance diagram for HistogramEditor:

Inheritance graph
[legend]
Collaboration diagram for HistogramEditor:

Collaboration graph
[legend]
List of all members.

Detailed Description

Interface for adjusting image historgram using upper and lower bounds and bright and contrast controls.

Definition at line 31 of file histogramEditor.h.

Public Member Functions

 HistogramEditor (QString filename, QWidget *parent=0, const char *name=0)
 Constructs layout.
 ~HistogramEditor ()
QImage * getModifiedImage ()
 get modified image that resulted from adjustments
void getHistBoundaries (int &lumLeft, int &lumRight, int &redLeft, int &redRight, int &greenLeft, int &greenRight, int &blueLeft, int &blueRight)
 returns histogram boundaries

Protected Member Functions

void keyPressEvent (QKeyEvent *e)
void keyReleaseEvent (QKeyEvent *e)

Private Slots

void selectPreviewImageType (int selection)
 updates preview image
void selectHistogramType (int selection)
 updates historgram interface
void resetBrightness ()
 reset brightness
void resetContrast ()
 reset contrast
void applyAction ()
 check for changes to settings, if so
void resetAction ()
 resets all adjustments
void generateAdjustedPreviewImage ()
 updates adjusted preview image

Private Member Functions

void adjustImage (QImage &image)
double scaleColor (double color, int left, int right)

Private Attributes

QString fileName
double meanR
 Mean color values.
double meanG
 Mean color values.
double meanB
 Mean color values.
ScaledPreviewInterfacepreviewInterface
 Preview image.
HistogramInterfacehistogramInterface
 Histogram view.
QComboBox * previewSelection
QComboBox * histogramType
ClickableLabelbrightnessIcon
ClickableLabelcontrastIcon
QFramebuttonsFrame
DynamicSliderbrightness
 Brightness slider.
DynamicSlidercontrast
 Contrast slider.


Constructor & Destructor Documentation

HistogramEditor::HistogramEditor QString  filename,
QWidget parent = 0,
const char *  name = 0
 

Constructs layout.

Definition at line 33 of file histogramEditor.cpp.

References applyAction(), b, brightness, brightnessIcon, buttonsFrame, contrast, contrastIcon, generateAdjustedPreviewImage(), histogramInterface, histogramType, IMAGE_PATH, meanB, meanG, meanR, previewInterface, previewSelection, resetAction(), resetBrightness(), resetContrast(), selectHistogramType(), selectPreviewImageType(), ClickableLabel::setPixmap(), DynamicSlider::setPrefixes(), DynamicSlider::setZeroString(), SLIDER_RADIUS, and WIDGET_SPACING.

00033                                                                                       : QDialog(parent,name,true)
00034 {
00035   //set pointer to null to make sure no 
00036   //random data is ever accessed by the preview interface
00037   histogramInterface = NULL;
00038 
00039   //record filename
00040   this->fileName = fileName;
00041   
00042   //-----
00043   //find mean color values
00044   meanR = 0;
00045   meanG = 0;
00046   meanB = 0;
00047   int x, y;
00048   QRgb* rgb;
00049   uchar* scanLine;
00050   QImage image = QImage( fileName );
00051   for( y=0; y<image.height(); y++)
00052   {   
00053     scanLine = image.scanLine(y);
00054     for( x=0; x<image.width(); x++)
00055     {
00056       rgb = ((QRgb*)scanLine+x);
00057       double r = ((double)qRed(*rgb)   )/255.0;
00058       double g = ((double)qGreen(*rgb) )/255.0;
00059       double b = ((double)qBlue(*rgb)  )/255.0;
00060       
00061       meanR+=r;
00062       meanG+=g;
00063       meanB+=b;
00064     } //x
00065   } //y
00066   meanR = meanR / ( image.width() * image.height() );
00067   meanG = meanG / ( image.width() * image.height() );
00068   meanB = meanB / ( image.width() * image.height() );
00069   
00070   QFrame* visibleFrame = new QFrame( this, "visible widgets" );
00071   //--------------  
00072   //Preview frame: 
00073   previewInterface = new ScaledPreviewInterface( fileName, visibleFrame, 
00074                                                  "previewInterface" );
00075   connect( previewInterface, SIGNAL(resized()), 
00076            this, SLOT(generateAdjustedPreviewImage()) );  
00077 
00078   previewSelection = new QComboBox( visibleFrame, "previewSelction" );
00079   previewSelection->insertItem( tr("Split View") );
00080   previewSelection->insertItem( tr("Original Image") );
00081   previewSelection->insertItem( tr("Adjusted Image") );
00082   connect( previewSelection, SIGNAL(activated(int)), this, SLOT(selectPreviewImageType(int)) );  
00083   //--------------
00084   //Adjust frame:   
00085   histogramInterface = new HistogramInterface( fileName, visibleFrame, 
00086                                                "histogramInterface" );  
00087 
00088   //connect adjustments in histogram to generateAdjustedPreviewImage
00089   connect( histogramInterface, SIGNAL( selectedRangeChanged() ),
00090            SLOT( generateAdjustedPreviewImage() ) );
00091   
00092   QToolTip::add( histogramInterface, tr("Click and drag to select tonal range") );  
00093 
00094   histogramType = new QComboBox( visibleFrame, "histogramType" );
00095   histogramType->insertItem( tr("Luminosity") );
00096   histogramType->insertItem( tr("Red") );
00097   histogramType->insertItem( tr("Green") );
00098   histogramType->insertItem( tr("Blue") );  
00099   connect( histogramType, SIGNAL(activated(int)), this, SLOT(selectHistogramType(int)) );  
00100   QToolTip::add( histogramType, tr("Histogram channel displayed") );  
00101   //--------------
00102   //Slider frame:
00103   QString noChange = QString( tr("No change") );
00104   
00105   brightness = new DynamicSlider( Qt::Vertical, visibleFrame );
00106   brightness->setZeroString( noChange );
00107   brightness->setPrefixes("", "+");
00108   brightness->setMinValue( -SLIDER_RADIUS );
00109   brightness->setMaxValue( SLIDER_RADIUS );
00110   connect( brightness, SIGNAL(valueChanged(int)),
00111            this, SLOT(generateAdjustedPreviewImage()) );;
00112   QToolTip::add( brightness, tr("Drag to adjust image brightness") );  
00113            
00114   brightnessIcon = new ClickableLabel( visibleFrame, "brightnessIcon" );
00115   brightnessIcon->setPixmap( QPixmap(QString(IMAGE_PATH)+"miscImages/brightness.png") );
00116   connect( brightnessIcon, SIGNAL(clicked()), SLOT(resetBrightness()) );    
00117   QToolTip::add( brightnessIcon, tr("Reset brightness") );
00118 
00119   contrast = new DynamicSlider( Qt::Vertical, visibleFrame );
00120   contrast->setZeroString( noChange );
00121   contrast->setPrefixes("", "+");
00122   contrast->setMinValue( -SLIDER_RADIUS );
00123   contrast->setMaxValue( SLIDER_RADIUS );
00124   connect( contrast, SIGNAL(valueChanged(int)),
00125            this, SLOT(generateAdjustedPreviewImage()) );
00126   QToolTip::add( contrast, tr("Drag to adjust image contrast") );  
00127 
00128   contrastIcon = new ClickableLabel( visibleFrame, "contrastIcon" );
00129   contrastIcon->setPixmap( QPixmap(QString(IMAGE_PATH)+"miscImages/contrast.png") );
00130   connect( contrastIcon, SIGNAL(clicked()), SLOT(resetContrast()) );    
00131   QToolTip::add( contrastIcon, tr("Reset contrast") );
00132   //--------------
00133   //Dialog buttons:  
00134   buttonsFrame =   new QFrame( visibleFrame, "dialogButtons" );
00135 
00136   QPushButton* applyButton = new QPushButton( tr("Apply"), buttonsFrame );
00137   applyButton->setDefault(true);
00138   applyButton->setFocus();
00139   connect( applyButton, SIGNAL(clicked()), SLOT(applyAction()) );
00140                                 
00141   QPushButton* cancelButton = new QPushButton( tr("Cancel"), buttonsFrame );
00142   connect( cancelButton, SIGNAL(clicked()), SLOT(reject()) );
00143 
00144   QPushButton* resetButton = new QPushButton( tr("Reset"), buttonsFrame );
00145   connect( resetButton, SIGNAL(clicked()), SLOT(resetAction()) );
00146 
00147   QGridLayout* buttonsGrid = new QGridLayout( buttonsFrame, 1, 5, 0 );
00148   buttonsGrid->setColStretch( 0, 1 );
00149   buttonsGrid->addWidget( applyButton,  0, 1 );
00150   buttonsGrid->addWidget( cancelButton, 0, 2 );
00151   buttonsGrid->addWidget( resetButton, 0, 3 );
00152   buttonsGrid->setColStretch( 4, 1 );  
00153   buttonsGrid->setSpacing( WIDGET_SPACING );
00154   //--------------
00155   QGridLayout* mainGrid = new QGridLayout( visibleFrame, 5, 3, 0 );
00156   
00157   mainGrid->addMultiCellWidget( previewInterface,     0,0, 0,2 );
00158   mainGrid->addMultiCellWidget( previewSelection, 1,1, 0,2, Qt::AlignHCenter );  
00159    
00160   mainGrid->addWidget( histogramInterface,    2, 0 ); 
00161   mainGrid->addWidget( brightness,            2, 1 );
00162   mainGrid->addWidget( contrast,              2, 2 );
00163   
00164   //make sure sliders have enough space so all slider units are settable
00165   mainGrid->setRowSpacing( 2, 2*SLIDER_RADIUS + 5) ;
00166     
00167   mainGrid->addWidget( histogramType,    3, 0, Qt::AlignHCenter );
00168   mainGrid->addWidget( brightnessIcon,   3, 1 );  
00169   mainGrid->addWidget( contrastIcon,     3, 2 );  
00170   
00171   mainGrid->addMultiCellWidget( buttonsFrame, 4,4, 0,2 );
00172 
00173   mainGrid->setRowStretch( 0, 1 );
00174   mainGrid->setColStretch( 0, 1 );
00175   
00176   mainGrid->setSpacing( WIDGET_SPACING );
00177   mainGrid->setMargin( WIDGET_SPACING );
00178   
00179   QGridLayout* invisibleGrid = new QGridLayout( this, 2, 1, 0 );
00180   invisibleGrid->addWidget( visibleFrame, 0, 0 );
00181   invisibleGrid->setRowStretch( 0, 1 );
00182   
00183   //PLATFORM_SPECIFIC_CODE
00184   //windows users expect a grip, but qt doesn't put one in by default. we'll add
00185   //it for them too. :-)
00186 #if defined(Q_OS_WIN)
00187   QSizeGrip* sizeGrip = new QSizeGrip( this );
00188   invisibleGrid->addWidget( sizeGrip, 1, 0, Qt::AlignRight | Qt::AlignBottom );
00189 #endif
00190   
00191   
00192   
00193   
00194   //Window caption
00195   setCaption( tr("Album Shaper: Histogram Editor") );
00196   //-------------------------------
00197 }

HistogramEditor::~HistogramEditor  ) 
 

Definition at line 199 of file histogramEditor.cpp.

00199 { }


Member Function Documentation

void HistogramEditor::adjustImage QImage &  image  )  [private]
 

Definition at line 286 of file histogramEditor.cpp.

References b, brightness, contrast, HistogramInterface::getHistBoundaries(), histogramInterface, HSVtoRGB(), meanB, meanG, meanR, RGBtoHSV(), scaleColor(), and SLIDER_RADIUS.

Referenced by generateAdjustedPreviewImage(), and getModifiedImage().

00287 {
00288   //obtain histogram left and right boundaries
00289   //sanity check
00290   int lumLeft, lumRight, redLeft, redRight, greenLeft, greenRight, blueLeft, blueRight;
00291   if( histogramInterface )
00292   {
00293     histogramInterface->getHistBoundaries( lumLeft, lumRight,
00294                                            redLeft, redRight,
00295                                            greenLeft, greenRight,
00296                                            blueLeft, blueRight );
00297   }
00298   else
00299   {
00300     lumLeft = 0; lumRight = 255;
00301     redLeft = 0; redRight = 255;
00302     greenLeft = 0; greenRight = 255;
00303     blueLeft = 0; blueRight = 255;
00304   }
00305   
00306   //modify image
00307   double displayToOneScalar = 1.0/255.0;
00308   double scaledMeanR = displayToOneScalar*scaleColor( 255.0*meanR, redLeft, redRight );
00309   double scaledMeanG = displayToOneScalar*scaleColor( 255.0*meanG, greenLeft, greenRight );
00310   double scaledMeanB = displayToOneScalar*scaleColor( 255.0*meanB, blueLeft, blueRight );
00311   
00312   double brightnessScalar, addedBrightnessColor;
00313   if(brightness->value() < 0)
00314   {
00315     brightnessScalar = ((double)(SLIDER_RADIUS + brightness->value()))/SLIDER_RADIUS;
00316     addedBrightnessColor = 1.0 - brightnessScalar;
00317   }
00318   else
00319   {
00320     brightnessScalar = ((double)(SLIDER_RADIUS - brightness->value()))/SLIDER_RADIUS;
00321     addedBrightnessColor = 0.0;
00322   }
00323   
00324   int x, y;  
00325   QRgb* rgb;
00326   double r,g,b;
00327   double h,s,v;
00328   int rPrime, gPrime, bPrime;
00329   uchar* scanLine;
00330   
00331   for( y=0; y<image.height(); y++)
00332   {   
00333     scanLine = image.scanLine(y);
00334     for( x=0; x<image.width(); x++)
00335     {
00336       //get rgb value
00337       rgb = ((QRgb*)scanLine+x);
00338       r = qRed(*rgb);
00339       g = qGreen(*rgb);
00340       b = qBlue(*rgb);
00341       
00342       //apply histogram boundaries
00343       RGBtoHSV(r,g,b,&h,&s,&v);
00344       v = scaleColor( v, lumLeft, lumRight );
00345       HSVtoRGB( &r,&g,&b, h,s,v);         
00346       
00347       r = scaleColor( r, redLeft, redRight );
00348       g = scaleColor( g, greenLeft, greenRight );
00349       b = scaleColor( b, blueLeft, blueRight );
00350       
00351       //convert to 0-1 scale
00352       r = r*displayToOneScalar;
00353       g = g*displayToOneScalar;
00354       b = b*displayToOneScalar;
00355       
00356       //adjust contrast
00357       r = ( (r-scaledMeanR) * (SLIDER_RADIUS-contrast->value()) )/SLIDER_RADIUS + scaledMeanR;
00358       g = ( (g-scaledMeanG) * (SLIDER_RADIUS-contrast->value()) )/SLIDER_RADIUS + scaledMeanG;
00359       b = ( (b-scaledMeanB) * (SLIDER_RADIUS-contrast->value()) )/SLIDER_RADIUS + scaledMeanB;
00360       
00361       //apply brightness adjustment
00362       //http://www.sgi.com/misc/grafica/interp/
00363       r = brightnessScalar*r + addedBrightnessColor;
00364       g = brightnessScalar*g + addedBrightnessColor;
00365       b = brightnessScalar*b + addedBrightnessColor;
00366       
00367       //scale and clamp to 0-255 range
00368       rPrime = (int) QMIN( QMAX((r*255), 0), 255 );
00369       gPrime = (int) QMIN( QMAX((g*255), 0), 255 );
00370       bPrime = (int) QMIN( QMAX((b*255), 0), 255 );
00371       
00372       //set adjusted color value
00373       *rgb = qRgb(rPrime, gPrime, bPrime);          
00374     } //x
00375   } //y  
00376 }

void HistogramEditor::applyAction  )  [private, slot]
 

check for changes to settings, if so

Definition at line 201 of file histogramEditor.cpp.

References brightness, contrast, HistogramInterface::getHistBoundaries(), and histogramInterface.

Referenced by HistogramEditor().

00202 {
00203   //check if user has adjusted brightness, contrast, or histogram ranges.
00204   //if any changes have taken place call "accept", else "reject" so image is not
00205   //updated and appear modified
00206   int lumLeft, lumRight, redLeft, redRight, greenLeft, greenRight, blueLeft, blueRight;
00207   histogramInterface->getHistBoundaries( lumLeft, lumRight,
00208                                          redLeft, redRight,
00209                                          greenLeft, greenRight,
00210                                          blueLeft, blueRight );  
00211   if( brightness->value() != 0 || contrast->value()   != 0 ||
00212       lumLeft != 0 || lumRight != 255 ||
00213       redLeft !=0 || redRight != 255 ||
00214       greenLeft != 0 || greenRight != 255 ||
00215       blueLeft != 0 || blueRight != 255 )
00216   { accept(); }
00217   else
00218   { reject(); }  
00219 }

void HistogramEditor::generateAdjustedPreviewImage  )  [private, slot]
 

updates adjusted preview image

Definition at line 273 of file histogramEditor.cpp.

References adjustImage(), SplitViewInterface::getOrigImage(), previewInterface, and SplitViewInterface::setAdjustedImage().

Referenced by HistogramEditor().

00274 {
00275   //get original image
00276   QImage origImage = previewInterface->getOrigImage();
00277 
00278   //construct adjusted image
00279   QImage adjustedImage = origImage.copy();
00280   adjustImage( adjustedImage );
00281   
00282   //set adjusted image
00283   previewInterface->setAdjustedImage( adjustedImage );
00284 }

void HistogramEditor::getHistBoundaries int &  lumLeft,
int &  lumRight,
int &  redLeft,
int &  redRight,
int &  greenLeft,
int &  greenRight,
int &  blueLeft,
int &  blueRight
 

returns histogram boundaries

Definition at line 251 of file histogramEditor.cpp.

References HistogramInterface::getHistBoundaries(), and histogramInterface.

00255 {
00256   //sanity check
00257   if( histogramInterface )
00258   {
00259     histogramInterface->getHistBoundaries( lumLeft, lumRight,
00260                                            redLeft, redRight,
00261                                            greenLeft, greenRight,
00262                                            blueLeft, blueRight );
00263   }
00264   else
00265   {
00266     lumLeft = 0; lumRight = 255;
00267     redLeft = 0; redRight = 255;
00268     greenLeft = 0; greenRight = 255;
00269     blueLeft = 0; blueRight = 255;
00270   }
00271 }

QImage * HistogramEditor::getModifiedImage  ) 
 

get modified image that resulted from adjustments

Definition at line 228 of file histogramEditor.cpp.

References adjustImage(), and fileName.

00229 { 
00230   QImage* adjustedImage = new QImage(fileName);
00231   adjustImage( *adjustedImage );
00232   return adjustedImage;  
00233 }

void HistogramEditor::keyPressEvent QKeyEvent *  e  )  [protected]
 

Definition at line 383 of file histogramEditor.cpp.

References ADJUSTED_IMAGE, INV_SPLIT_VIEW, ORIGINAL_IMAGE, PREVIEW_MODE, previewInterface, previewSelection, and SplitViewInterface::setPreviewMode().

00384 {
00385   if(e->key() == Qt::Key_Control )
00386   {
00387     PREVIEW_MODE curMode = (PREVIEW_MODE) previewSelection->currentItem();
00388     if(curMode == ORIGINAL_IMAGE)
00389       previewInterface->setPreviewMode( ADJUSTED_IMAGE, true );
00390     else if(curMode == ADJUSTED_IMAGE)
00391       previewInterface->setPreviewMode( ORIGINAL_IMAGE, true );
00392     else
00393       previewInterface->setPreviewMode( INV_SPLIT_VIEW );
00394   }
00395   else { QDialog::keyPressEvent(e); }
00396 }

void HistogramEditor::keyReleaseEvent QKeyEvent *  e  )  [protected]
 

Definition at line 398 of file histogramEditor.cpp.

References PREVIEW_MODE, previewInterface, previewSelection, and SplitViewInterface::setPreviewMode().

00399 {
00400   if(e->key() == Qt::Key_Control )
00401   {
00402     previewInterface->setPreviewMode( (PREVIEW_MODE) previewSelection->currentItem(), 
00403                                       false );
00404   }
00405   else { QDialog::keyReleaseEvent(e); }
00406 }

void HistogramEditor::resetAction  )  [private, slot]
 

resets all adjustments

Definition at line 221 of file histogramEditor.cpp.

References histogramInterface, HistogramInterface::resetBoundaries(), resetBrightness(), and resetContrast().

Referenced by HistogramEditor().

00222 {
00223   histogramInterface->resetBoundaries();
00224   resetBrightness();
00225   resetContrast();
00226 }

void HistogramEditor::resetBrightness  )  [private, slot]
 

reset brightness

Definition at line 245 of file histogramEditor.cpp.

References brightness.

Referenced by HistogramEditor(), and resetAction().

00246 { brightness->setValue( 0 ); }

void HistogramEditor::resetContrast  )  [private, slot]
 

reset contrast

Definition at line 248 of file histogramEditor.cpp.

References contrast.

Referenced by HistogramEditor(), and resetAction().

00249 { contrast->setValue( 0 ); }

double HistogramEditor::scaleColor double  color,
int  left,
int  right
[private]
 

Definition at line 378 of file histogramEditor.cpp.

Referenced by adjustImage().

00379 {
00380   return QMAX( QMIN( (255.0*(color-left)) / (right-left), 255), 0 );  
00381 }

void HistogramEditor::selectHistogramType int  selection  )  [private, slot]
 

updates historgram interface

Definition at line 240 of file histogramEditor.cpp.

References DISPLAYED_CHANNEL, histogramInterface, and HistogramInterface::setDisplayChannel().

Referenced by HistogramEditor().

00241 {
00242   histogramInterface->setDisplayChannel( (DISPLAYED_CHANNEL) selection );
00243 }

void HistogramEditor::selectPreviewImageType int  selection  )  [private, slot]
 

updates preview image

Definition at line 235 of file histogramEditor.cpp.

References PREVIEW_MODE, previewInterface, and SplitViewInterface::setPreviewMode().

Referenced by HistogramEditor().

00236 {
00237   previewInterface->setPreviewMode( (PREVIEW_MODE)selection );
00238 }


Member Data Documentation

DynamicSlider* HistogramEditor::brightness [private]
 

Brightness slider.

Definition at line 105 of file histogramEditor.h.

Referenced by adjustImage(), applyAction(), HistogramEditor(), and resetBrightness().

ClickableLabel* HistogramEditor::brightnessIcon [private]
 

Definition at line 99 of file histogramEditor.h.

Referenced by HistogramEditor().

QFrame* HistogramEditor::buttonsFrame [private]
 

Definition at line 101 of file histogramEditor.h.

Referenced by HistogramEditor().

DynamicSlider* HistogramEditor::contrast [private]
 

Contrast slider.

Definition at line 108 of file histogramEditor.h.

Referenced by adjustImage(), applyAction(), HistogramEditor(), and resetContrast().

ClickableLabel* HistogramEditor::contrastIcon [private]
 

Definition at line 100 of file histogramEditor.h.

Referenced by HistogramEditor().

QString HistogramEditor::fileName [private]
 

Definition at line 86 of file histogramEditor.h.

Referenced by getModifiedImage().

HistogramInterface* HistogramEditor::histogramInterface [private]
 

Histogram view.

Definition at line 95 of file histogramEditor.h.

Referenced by adjustImage(), applyAction(), getHistBoundaries(), HistogramEditor(), resetAction(), and selectHistogramType().

QComboBox* HistogramEditor::histogramType [private]
 

Definition at line 98 of file histogramEditor.h.

Referenced by HistogramEditor().

double HistogramEditor::meanB [private]
 

Mean color values.

Definition at line 89 of file histogramEditor.h.

Referenced by adjustImage(), and HistogramEditor().

double HistogramEditor::meanG [private]
 

Mean color values.

Definition at line 89 of file histogramEditor.h.

Referenced by adjustImage(), and HistogramEditor().

double HistogramEditor::meanR [private]
 

Mean color values.

Definition at line 89 of file histogramEditor.h.

Referenced by adjustImage(), and HistogramEditor().

ScaledPreviewInterface* HistogramEditor::previewInterface [private]
 

Preview image.

Definition at line 92 of file histogramEditor.h.

Referenced by generateAdjustedPreviewImage(), HistogramEditor(), keyPressEvent(), keyReleaseEvent(), and selectPreviewImageType().

QComboBox* HistogramEditor::previewSelection [private]
 

Definition at line 97 of file histogramEditor.h.

Referenced by HistogramEditor(), keyPressEvent(), and keyReleaseEvent().


The documentation for this class was generated from the following files:
Generated on Sat Apr 2 05:44:59 2005 for AlbumShaper by  doxygen 1.3.9.1