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(
"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
00232
00233
if( adjustedImage->depth() < 32 )
00234 {
00235 QImage* tmp = adjustedImage;
00236 adjustedImage =
new QImage( tmp->convertDepth( 32, Qt::AutoColor ) );
00237
delete tmp; tmp=NULL;
00238 }
00239
00240
adjustImage( *adjustedImage );
00241
return adjustedImage;
00242 }
00243
00244 void HistogramEditor::selectPreviewImageType(
int selection )
00245 {
00246
previewInterface->
setPreviewMode( (
PREVIEW_MODE)selection );
00247 }
00248
00249 void HistogramEditor::selectHistogramType(
int selection )
00250 {
00251
histogramInterface->
setDisplayChannel( (
DISPLAYED_CHANNEL) selection );
00252 }
00253
00254 void HistogramEditor::resetBrightness()
00255 {
brightness->setValue( 0 ); }
00256
00257 void HistogramEditor::resetContrast()
00258 {
contrast->setValue( 0 ); }
00259
00260 void HistogramEditor::getHistBoundaries(
int &lumLeft,
int &lumRight,
00261
int &redLeft,
int &redRight,
00262
int &greenLeft,
int &greenRight,
00263
int &blueLeft,
int &blueRight)
00264 {
00265
00266
if(
histogramInterface )
00267 {
00268
histogramInterface->
getHistBoundaries( lumLeft, lumRight,
00269 redLeft, redRight,
00270 greenLeft, greenRight,
00271 blueLeft, blueRight );
00272 }
00273
else
00274 {
00275 lumLeft = 0; lumRight = 255;
00276 redLeft = 0; redRight = 255;
00277 greenLeft = 0; greenRight = 255;
00278 blueLeft = 0; blueRight = 255;
00279 }
00280 }
00281
00282 void HistogramEditor::generateAdjustedPreviewImage()
00283 {
00284
00285 QImage origImage =
previewInterface->
getOrigImage();
00286
00287
00288 QImage adjustedImage = origImage.copy();
00289
adjustImage( adjustedImage );
00290
00291
00292
previewInterface->
setAdjustedImage( adjustedImage );
00293 }
00294
00295 void HistogramEditor::adjustImage( QImage &image )
00296 {
00297
00298
00299
int lumLeft, lumRight, redLeft, redRight, greenLeft, greenRight, blueLeft, blueRight;
00300
if(
histogramInterface )
00301 {
00302
histogramInterface->
getHistBoundaries( lumLeft, lumRight,
00303 redLeft, redRight,
00304 greenLeft, greenRight,
00305 blueLeft, blueRight );
00306 }
00307
else
00308 {
00309 lumLeft = 0; lumRight = 255;
00310 redLeft = 0; redRight = 255;
00311 greenLeft = 0; greenRight = 255;
00312 blueLeft = 0; blueRight = 255;
00313 }
00314
00315
00316
double displayToOneScalar = 1.0/255.0;
00317
double scaledMeanR = displayToOneScalar*
scaleColor( 255.0*
meanR, redLeft, redRight );
00318
double scaledMeanG = displayToOneScalar*scaleColor( 255.0*
meanG, greenLeft, greenRight );
00319
double scaledMeanB = displayToOneScalar*scaleColor( 255.0*
meanB, blueLeft, blueRight );
00320
00321
double brightnessScalar, addedBrightnessColor;
00322
if(
brightness->value() < 0)
00323 {
00324 brightnessScalar = ((
double)(
SLIDER_RADIUS +
brightness->value()))/
SLIDER_RADIUS;
00325 addedBrightnessColor = 1.0 - brightnessScalar;
00326 }
00327
else
00328 {
00329 brightnessScalar = ((
double)(
SLIDER_RADIUS -
brightness->value()))/
SLIDER_RADIUS;
00330 addedBrightnessColor = 0.0;
00331 }
00332
00333
int x, y;
00334 QRgb* rgb;
00335
double r,g,
b;
00336
double h,s,v;
00337
int rPrime, gPrime, bPrime;
00338 uchar* scanLine;
00339
00340
for( y=0; y<image.height(); y++)
00341 {
00342 scanLine = image.scanLine(y);
00343
for( x=0; x<image.width(); x++)
00344 {
00345
00346 rgb = ((QRgb*)scanLine+x);
00347 r = qRed(*rgb);
00348 g = qGreen(*rgb);
00349
b = qBlue(*rgb);
00350
00351
00352
RGBtoHSV(r,g,
b,&h,&s,&v);
00353 v = scaleColor( v, lumLeft, lumRight );
00354
HSVtoRGB( &r,&g,&
b, h,s,v);
00355
00356 r = scaleColor( r, redLeft, redRight );
00357 g = scaleColor( g, greenLeft, greenRight );
00358
b = scaleColor(
b, blueLeft, blueRight );
00359
00360
00361 r = r*displayToOneScalar;
00362 g = g*displayToOneScalar;
00363
b =
b*displayToOneScalar;
00364
00365
00366 r = ( (r-scaledMeanR) * (
SLIDER_RADIUS-
contrast->value()) )/
SLIDER_RADIUS + scaledMeanR;
00367 g = ( (g-scaledMeanG) * (
SLIDER_RADIUS-
contrast->value()) )/
SLIDER_RADIUS + scaledMeanG;
00368
b = ( (
b-scaledMeanB) * (
SLIDER_RADIUS-
contrast->value()) )/
SLIDER_RADIUS + scaledMeanB;
00369
00370
00371
00372 r = brightnessScalar*r + addedBrightnessColor;
00373 g = brightnessScalar*g + addedBrightnessColor;
00374
b = brightnessScalar*
b + addedBrightnessColor;
00375
00376
00377 rPrime = (
int) QMIN( QMAX((r*255), 0), 255 );
00378 gPrime = (
int) QMIN( QMAX((g*255), 0), 255 );
00379 bPrime = (
int) QMIN( QMAX((
b*255), 0), 255 );
00380
00381
00382 *rgb = qRgb(rPrime, gPrime, bPrime);
00383 }
00384 }
00385 }
00386
00387 double HistogramEditor::scaleColor(
double color,
int left,
int right )
00388 {
00389
return QMAX( QMIN( (255.0*(color-left)) / (right-left), 255), 0 );
00390 }
00391
00392 void HistogramEditor::keyPressEvent(QKeyEvent *e)
00393 {
00394
if(e->key() == Qt::Key_Control )
00395 {
00396
PREVIEW_MODE curMode = (
PREVIEW_MODE)
previewSelection->currentItem();
00397
if(curMode ==
ORIGINAL_IMAGE)
00398
previewInterface->
setPreviewMode(
ADJUSTED_IMAGE,
true );
00399
else if(curMode ==
ADJUSTED_IMAGE)
00400
previewInterface->
setPreviewMode(
ORIGINAL_IMAGE,
true );
00401
else
00402
previewInterface->
setPreviewMode(
INV_SPLIT_VIEW );
00403 }
00404
else { QDialog::keyPressEvent(e); }
00405 }
00406
00407 void HistogramEditor::keyReleaseEvent(QKeyEvent *e)
00408 {
00409
if(e->key() == Qt::Key_Control )
00410 {
00411
previewInterface->
setPreviewMode( (
PREVIEW_MODE)
previewSelection->currentItem(),
00412
false );
00413 }
00414
else { QDialog::keyReleaseEvent(e); }
00415 }
00416
00417
00418