00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00022 #include "histogramEditor.h"
00023 #include "scaledPreviewInterface.h"
00024 #include "histogramInterface.h"
00025 #include "../clickableLabel.h"
00026 #include "../dynamicSlider.h"
00027 #include "../../config.h"
00028 #include "../../backend/tools/imageTools.h"
00029
00030 #define SLIDER_RADIUS 40
00031
00032
00033 HistogramEditor::HistogramEditor( QString fileName, QWidget *parent, const char* name ) : QDialog(parent,name,true)
00034 {
00035
00036
00037 histogramInterface = NULL;
00038
00039
00040 this->fileName = fileName;
00041
00042
00043
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 }
00065 }
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
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
00085 histogramInterface = new HistogramInterface( fileName, visibleFrame,
00086 "histogramInterface" );
00087
00088
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
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
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
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
00184
00185
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
00195 setCaption( tr("Album Shaper: Histogram Editor") );
00196
00197 }
00198
00199 HistogramEditor::~HistogramEditor() { }
00200
00201 void HistogramEditor::applyAction()
00202 {
00203
00204
00205
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 }
00220
00221 void HistogramEditor::resetAction()
00222 {
00223 histogramInterface->resetBoundaries();
00224 resetBrightness();
00225 resetContrast();
00226 }
00227
00228 QImage* HistogramEditor::getModifiedImage()
00229 {
00230 QImage* adjustedImage = new QImage(fileName);
00231 adjustImage( *adjustedImage );
00232 return adjustedImage;
00233 }
00234
00235 void HistogramEditor::selectPreviewImageType( int selection )
00236 {
00237 previewInterface->setPreviewMode( (PREVIEW_MODE)selection );
00238 }
00239
00240 void HistogramEditor::selectHistogramType( int selection )
00241 {
00242 histogramInterface->setDisplayChannel( (DISPLAYED_CHANNEL) selection );
00243 }
00244
00245 void HistogramEditor::resetBrightness()
00246 { brightness->setValue( 0 ); }
00247
00248 void HistogramEditor::resetContrast()
00249 { contrast->setValue( 0 ); }
00250
00251 void HistogramEditor::getHistBoundaries(int &lumLeft, int &lumRight,
00252 int &redLeft, int &redRight,
00253 int &greenLeft, int &greenRight,
00254 int &blueLeft, int &blueRight)
00255 {
00256
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 }
00272
00273 void HistogramEditor::generateAdjustedPreviewImage()
00274 {
00275
00276 QImage origImage = previewInterface->getOrigImage();
00277
00278
00279 QImage adjustedImage = origImage.copy();
00280 adjustImage( adjustedImage );
00281
00282
00283 previewInterface->setAdjustedImage( adjustedImage );
00284 }
00285
00286 void HistogramEditor::adjustImage( QImage &image )
00287 {
00288
00289
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
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
00337 rgb = ((QRgb*)scanLine+x);
00338 r = qRed(*rgb);
00339 g = qGreen(*rgb);
00340 b = qBlue(*rgb);
00341
00342
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
00352 r = r*displayToOneScalar;
00353 g = g*displayToOneScalar;
00354 b = b*displayToOneScalar;
00355
00356
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
00362
00363 r = brightnessScalar*r + addedBrightnessColor;
00364 g = brightnessScalar*g + addedBrightnessColor;
00365 b = brightnessScalar*b + addedBrightnessColor;
00366
00367
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
00373 *rgb = qRgb(rPrime, gPrime, bPrime);
00374 }
00375 }
00376 }
00377
00378 double HistogramEditor::scaleColor( double color, int left, int right )
00379 {
00380 return QMAX( QMIN( (255.0*(color-left)) / (right-left), 255), 0 );
00381 }
00382
00383 void HistogramEditor::keyPressEvent(QKeyEvent *e)
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 }
00397
00398 void HistogramEditor::keyReleaseEvent(QKeyEvent *e)
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 }
00407
00408
00409