#include <photoEditWidget.h>
Definition at line 40 of file photoEditWidget.h.
Public Member Functions | |
| PhotoEditWidget (QWidget *parent=0, const char *name=0) | |
| Creates layout. | |
| ~PhotoEditWidget () | |
| Deletes objects. | |
| void | setPhoto (Photo *photo) |
| Sets the photo pointer. | |
Private Slots | |
| void | updateDescription (const QString &val) |
| Updates photo description. | |
| void | adjustExposure () |
| Adjusts Exposure of entire image. | |
| void | cropToRegion () |
| Cropped image to selected region. | |
| void | invertSelection () |
| Inverts image. | |
| void | reduceRedeye () |
| Applies redeye reduction to selected region. | |
| void | resetImageAction () |
| Resets photo to state before editing took place. | |
| void | returnFromEdit () |
| Returns to organizing mode. | |
Private Attributes | |
| QGridLayout * | grid |
| Grid widgets are placed in. | |
| QFrame * | buttons |
| Grid lower buttons are placed in. | |
| QGridLayout * | grid2 |
| Grid for lower buttons. | |
| QLabel * | photoDescription |
| Label "Photo Description:". | |
| QLineEdit * | photoDescriptionVal |
| Actual photo description. | |
| Photo * | photo |
| Pointer to backend photo. | |
| QImage * | originalImage |
| Backup of image before any manipulations were preformed, allows user to reset image. | |
| PhotoViewWidget * | photoView |
| Photo view, provides interface to see image and select regions of it. | |
| QPixmap * | adjExposureImage |
| "Adj. Exposure" image | |
| QPushButton * | adjExposureButton |
| "Adj. Exposure" button | |
| QPixmap * | cropImage |
| "Crop" image | |
| QPushButton * | cropButton |
| "Crop" button | |
| QPixmap * | invertImage |
| "Invert" image | |
| QPushButton * | invertButton |
| "Invert" button | |
| QPixmap * | redEyeImage |
| "Red Eye" image | |
| QPushButton * | redEyeButton |
| "Red Eye" button | |
| QPixmap * | resetImage |
| "Reset" image | |
| QPushButton * | resetButton |
| "Reset" button | |
| QPixmap * | returnImage |
| "Return" image | |
| QPushButton * | returnButton |
| "Return" button | |
| LayoutWidget * | layout |
| Pointer to the parent layout widget. | |
|
||||||||||||
|
Creates layout.
Definition at line 41 of file photoEditWidget.cpp. References adjExposureButton, adjExposureImage, adjustExposure(), buttons, cropButton, cropImage, cropToRegion(), grid, grid2, IMAGE_PATH, invertButton, invertImage, invertSelection(), layout, originalImage, photo, photoDescription, photoDescriptionVal, photoView, redEyeButton, redEyeImage, reduceRedeye(), resetButton, resetImage, resetImageAction(), returnButton, returnFromEdit(), returnImage, and updateDescription().
00042 :
00043 QWidget(parent,name)
00044 {
00045 //set photo pointer to null by default
00046 photo = NULL;
00047
00048 //backup image null by default
00049 originalImage = NULL;
00050
00051 //store layout pointer
00052 layout = (LayoutWidget*)parent;
00053
00054 //create photo description labels
00055 photoDescription = new QLabel( this );
00056 photoDescription->setText( "Photo Description:" );
00057 photoDescription->setFont( QFont( "Times", 12, QFont::Bold ) );
00058 photoDescriptionVal = new QLineEdit( this );
00059 photoDescriptionVal->setFont( QFont( "Times", 12, QFont::Bold ) );
00060 connect( photoDescriptionVal, SIGNAL(textChanged(const QString&)),
00061 SLOT(updateDescription(const QString&)) );
00062
00063 //create photo label
00064 photoView = new PhotoViewWidget( this, "photo view" );
00065
00066 //create buttons
00067 buttons = new QFrame(this);
00068
00069 adjExposureImage = new QPixmap( QString(IMAGE_PATH)+"adjExposure.png" );
00070 adjExposureButton = new QPushButton( buttons );
00071 adjExposureButton->setPixmap( *adjExposureImage );
00072 adjExposureButton->setEnabled(false);
00073 connect( adjExposureButton, SIGNAL(clicked()), SLOT(adjustExposure()) );
00074
00075 cropImage = new QPixmap( QString(IMAGE_PATH)+"crop.png" );
00076 cropButton = new QPushButton( buttons );
00077 cropButton->setPixmap( *cropImage );
00078 connect( cropButton, SIGNAL(clicked()), SLOT(cropToRegion()) );
00079
00080 invertImage = new QPixmap( QString(IMAGE_PATH)+"invert.png" );
00081 invertButton = new QPushButton( buttons );
00082 invertButton->setPixmap( *invertImage );
00083 connect( invertButton, SIGNAL(clicked()), SLOT(invertSelection()) );
00084
00085 redEyeImage = new QPixmap( QString(IMAGE_PATH)+"removeRedEye.png" );
00086 redEyeButton = new QPushButton( buttons );
00087 redEyeButton->setPixmap( *redEyeImage );
00088 redEyeButton->setEnabled(false);
00089 connect( redEyeButton, SIGNAL(clicked()), SLOT(reduceRedeye()) );
00090
00091 resetImage = new QPixmap( QString(IMAGE_PATH)+"reset.png" );
00092 resetButton = new QPushButton( buttons );
00093 resetButton->setPixmap( *resetImage );
00094 connect( resetButton, SIGNAL(clicked()), SLOT(resetImageAction()) );
00095
00096 returnImage = new QPixmap( QString(IMAGE_PATH)+"return.png" );
00097 returnButton = new QPushButton( buttons );
00098 returnButton->setPixmap( *returnImage );
00099 connect( returnButton, SIGNAL(clicked()), SLOT(returnFromEdit()) );
00100
00101 //place all items in grid layout
00102 grid = new QGridLayout( this, 3, 3, 0 );
00103 grid->addWidget( photoDescription, 0, 0, Qt::AlignLeft );
00104 grid->addWidget( photoDescriptionVal, 0, 1 );
00105 grid->addMultiCellWidget( photoView, 1, 1, 0, 2, Qt::AlignCenter );
00106
00107 grid2 = new QGridLayout( buttons, 1, 8, 0 );
00108 grid2->addWidget( adjExposureButton, 0, 1, Qt::AlignLeft );
00109 grid2->addWidget( cropButton, 0, 2, Qt::AlignLeft );
00110 grid2->addWidget( invertButton, 0, 3, Qt::AlignLeft );
00111 grid2->addWidget( redEyeButton, 0, 4, Qt::AlignLeft );
00112 grid2->addWidget( resetButton, 0, 5, Qt::AlignLeft );
00113 grid2->addWidget( returnButton, 0, 6, Qt::AlignLeft );
00114
00115 //set first and last column of button grid to take up remaining space
00116 grid2->setColStretch( 0, 1 );
00117 grid2->setColStretch( 7, 1 );
00118 grid->addMultiCellWidget( buttons, 2, 2, 0, 2 );
00119
00120 //set the last column to stretch to fill any blank space
00121 grid->setColStretch( 2, 1 );
00122
00123 //set photo row to stretch to fill any blank space
00124 grid->setRowStretch( 1, 1 );
00125
00126 //Set the second column, the actual photo description
00127 //to have a minimum width
00128 grid->addColSpacing(1, 300 );
00129
00130 //set the background of the widget to be white
00131 setPaletteBackgroundColor( QColor(255, 255, 255) );
00132 }
|
|
|
Deletes objects.
Definition at line 134 of file photoEditWidget.cpp. References originalImage.
00135 {
00136 delete originalImage;
00137 originalImage = NULL;
00138 }
|
|
|
Adjusts Exposure of entire image. Set new image pointer and create all image forms Reload photo view If this is first manipulation to image then backup original, otherwise delete intermediate object Definition at line 178 of file photoEditWidget.cpp. References Photo::getImageFilename(), originalImage, photo, photoView, Photo::setImage(), and PhotoViewWidget::setPhoto(). Referenced by PhotoEditWidget().
00179 {
00180 //---------------------------------
00181 //load the full image
00182 QImage *backendImage = new QImage( photo->getImageFilename() );
00183 //---------------------------------------------
00184 //find mean and max log of luminance
00185 double delta = 0.00001;
00186 double max = 0.0;
00187 double sum = 0.0;
00188 double tmp, tmp2;
00189 int x;
00190 for(x=0; x<backendImage->width(); x++)
00191 {
00192 int y;
00193 for(y=0; y<backendImage->height(); y++)
00194 {
00195 QRgb val = backendImage->pixel( x, y );
00196 tmp = qGray(val);
00197 tmp = tmp / 255.0;
00198 tmp2 = log( tmp + delta );
00199
00200 sum+=tmp2;
00201 if(tmp > max)
00202 max = tmp;
00203 }
00204 }
00205 double avg = exp(sum/(backendImage->width() * backendImage->height()));
00206 cout << "max: " << max << endl;
00207 cout << "avg: " << avg << endl;
00208 double whiteSquared = max*max;
00209 //---------------------------------------------
00210 //create new image and fill in adjusted values
00211 QImage* equalizedImage = new QImage(backendImage->width(),
00212 backendImage->height(),
00213 backendImage->depth());
00214 double r, g, b;
00215 double alpha = 0.18;
00216 for(x=0; x<backendImage->width(); x++)
00217 {
00218 int y;
00219 for(y=0; y<backendImage->height(); y++)
00220 {
00221 QRgb val = backendImage->pixel( x, y );
00222 r = qRed(val); g = qGreen(val); b = qBlue(val);
00223 r = r/255.0; g = g/255.0; b = b/255.0;
00224
00225 r = (alpha/avg) * r;
00226 g = (alpha/avg) * g;
00227 b = (alpha/avg) * b;
00228
00229 r = (r * (1 + (r / whiteSquared))) / (1 + r);
00230 g = (g * (1 + (g / whiteSquared))) / (1 + g);
00231 b = (b * (1 + (b / whiteSquared))) / (1 + b);
00232
00233 r = r*255; g = g*255; b = b*255;
00234 val = qRgb( (int)r, (int)g, (int)b );
00235
00236 equalizedImage->setPixel( x, y, val );
00237 }
00238 }
00239 //---------------------------------
00242 if(originalImage == NULL)
00243 {
00244 originalImage = backendImage;
00245 }
00246 else
00247 {
00248 delete backendImage;
00249 backendImage = NULL;
00250 }
00251 //---------------------------------
00253 photo->setImage(equalizedImage);
00254
00255 //set image function deletes object once done so remove pointer to memory
00256 //we don't own any more
00257 equalizedImage = NULL;
00258 //---------------------------------
00260 photoView->setPhoto( photo );
00261 //---------------------------------
00262 }
|
|
|
Cropped image to selected region. Set new image pointer and create all image forms Reload photo view If this is first manipulation to image then backup original, otherwise delete intermediate object Definition at line 264 of file photoEditWidget.cpp. References Photo::actualSlideshowHeight(), Photo::actualSlideshowWidth(), Photo::getImageFilename(), PhotoViewWidget::getSelection(), originalImage, photo, photoView, Photo::setImage(), and PhotoViewWidget::setPhoto(). Referenced by PhotoEditWidget().
00265 {
00266 //---------------------------------
00267 //first get selected coordinates
00268 QPoint topLeft, bottomRight;
00269 photoView->getSelection(topLeft, bottomRight);
00270
00271 //if selection has no width or height then bail immediately
00272 if(bottomRight.x() - topLeft.x() == 0 ||
00273 bottomRight.y() - topLeft.y() == 0)
00274 {
00275 //scold user for not selection part of the image
00276
00277 return;
00278 }
00279 //---------------------------------
00280 //load the full image
00281 QImage *backendImage = new QImage( photo->getImageFilename() );
00282 //---------------------------------
00283 //scale the selected coordinates up into actual full size coordinates
00284 float widthRatio = (1.0f * backendImage->width()) / photo->actualSlideshowWidth();
00285 float heightRatio = (1.0f * backendImage->height()) / photo->actualSlideshowHeight();
00286
00287 //if user selected to end of photo fix selection to end rather
00288 //then scale and get numerical error which prevents selection
00289 //from running to edge ot photo
00290 if(bottomRight.x() == (photo->actualSlideshowWidth() - 1))
00291 bottomRight.setX( backendImage->width() - 1 );
00292 else
00293 bottomRight.setX( bottomRight.x() * widthRatio );
00294
00295 if(bottomRight.y() == (photo->actualSlideshowHeight() - 1))
00296 bottomRight.setY( backendImage->height() - 1 );
00297 else
00298 bottomRight.setY( bottomRight.y() * heightRatio );
00299 //---------------------------------
00300 //create new fullsize image
00301 QImage* croppedImage = new QImage(bottomRight.x() - topLeft.x() + 1,
00302 bottomRight.y() - topLeft.y() + 1,
00303 backendImage->depth());
00304 int newX, newY;
00305 newX = 0;
00306
00307 int x;
00308 for(x=topLeft.x(); x<= bottomRight.x(); x++)
00309 {
00310 newY = 0;
00311 int y;
00312 for(y=topLeft.y(); y<= bottomRight.y(); y++)
00313 {
00314 croppedImage->setPixel( newX, newY, backendImage->pixel(x, y) );
00315 newY++;
00316 }
00317 newX++;
00318 }
00319 //---------------------------------
00322 if(originalImage == NULL)
00323 {
00324 originalImage = backendImage;
00325 }
00326 else
00327 {
00328 delete backendImage;
00329 backendImage = NULL;
00330 }
00331 //---------------------------------
00333 photo->setImage(croppedImage);
00334
00335 //set image function deletes object once done so remove pointer to memory
00336 //we don't own any more
00337 croppedImage = NULL;
00338 //---------------------------------
00340 photoView->setPhoto( photo );
00341 //---------------------------------
00342 }
|
|
|
Inverts image. Set new image pointer and create all image forms Reload photo view If this is first manipulation to image then backup original, otherwise delete intermediate object Definition at line 344 of file photoEditWidget.cpp. References Photo::actualSlideshowHeight(), Photo::actualSlideshowWidth(), Photo::getImageFilename(), PhotoViewWidget::getSelection(), originalImage, photo, photoView, Photo::setImage(), and PhotoViewWidget::setPhoto(). Referenced by PhotoEditWidget().
00345 {
00346 //---------------------------------
00347 //first get selected coordinates
00348 QPoint topLeft, bottomRight;
00349 photoView->getSelection(topLeft, bottomRight);
00350 //---------------------------------
00351 //load the full image
00352 QImage *backendImage = new QImage( photo->getImageFilename() );
00353 //---------------------------------
00354 //if selected region is empty then invert entire image
00355 if(bottomRight.x() - topLeft.x() == 0 ||
00356 bottomRight.y() - topLeft.y() == 0)
00357 {
00358 topLeft.setX(0);
00359 topLeft.setY(0);
00360 bottomRight.setX(backendImage->width() - 1);
00361 bottomRight.setY(backendImage->height() - 1);
00362 }
00363 //else scale the selected coordinates up into actual full size coordinates
00364 else
00365 {
00366 float widthRatio = (1.0f * backendImage->width()) / photo->actualSlideshowWidth();
00367 float heightRatio = (1.0f * backendImage->height()) / photo->actualSlideshowHeight();
00368
00369 topLeft.setX( topLeft.x() * widthRatio );
00370 topLeft.setY( topLeft.y() * heightRatio );
00371
00372 //if user selected to end of photo fix selection to end rather
00373 //then scale and get numerical error which prevents selection
00374 //from running to edge ot photo
00375 if(bottomRight.x() == (photo->actualSlideshowWidth() - 1))
00376 bottomRight.setX( backendImage->width() - 1 );
00377 else
00378 bottomRight.setX( bottomRight.x() * widthRatio );
00379
00380 if(bottomRight.y() == (photo->actualSlideshowHeight() - 1))
00381 bottomRight.setY( backendImage->height() - 1 );
00382 else
00383 bottomRight.setY( bottomRight.y() * heightRatio );
00384 }
00385 //---------------------------------
00386 //invert image
00387 QImage* invertedImage = new QImage(backendImage->width(),
00388 backendImage->height(),
00389 backendImage->depth());
00390 int x;
00391 for(x=0; x<backendImage->width(); x++)
00392 {
00393 int y;
00394 for(y=0; y<backendImage->height(); y++)
00395 {
00396 //if within selected region invert color
00397 if( x >= topLeft.x() && x <= bottomRight.x() &&
00398 y >= topLeft.y() && y <= bottomRight.y())
00399 {
00400 QRgb val = backendImage->pixel( x, y );
00401 val = qRgb( 255 - qRed(val), 255 - qGreen(val), 255 - qBlue(val) );
00402 invertedImage->setPixel( x, y, val );
00403 }
00404 //otherwise copy color
00405 else
00406 {
00407 invertedImage->setPixel( x, y, backendImage->pixel(x, y) );
00408 }
00409 }
00410 }
00411 //---------------------------------
00414 if(originalImage == NULL)
00415 {
00416 originalImage = backendImage;
00417 }
00418 else
00419 {
00420 delete backendImage;
00421 backendImage = NULL;
00422 }
00423 //---------------------------------
00425 photo->setImage(invertedImage);
00426
00427 //set image function deletes object once done so remove pointer to memory
00428 //we don't own any more
00429 invertedImage = NULL;
00430 //---------------------------------
00432 photoView->setPhoto( photo );
00433 //---------------------------------
00434 }
|
|
|
Applies redeye reduction to selected region.
Definition at line 436 of file photoEditWidget.cpp. Referenced by PhotoEditWidget().
00437 {
00438
00439 }
|
|
|
Resets photo to state before editing took place. Set new image pointer and create all image forms Reload photo view Definition at line 441 of file photoEditWidget.cpp. References originalImage, photo, photoView, Photo::setImage(), and PhotoViewWidget::setPhoto(). Referenced by PhotoEditWidget(), and returnFromEdit().
00442 {
00443 //if previous state saved revert all changes
00444 if(originalImage != NULL)
00445 {
00447 photo->setImage(originalImage);
00448
00449 //set image function deletes object once done so remove pointer to memory
00450 //we don't own any more
00451 originalImage = NULL;
00452
00454 photoView->setPhoto( photo );
00455 }
00456 }
|
|
|
Returns to organizing mode.
Definition at line 458 of file photoEditWidget.cpp. References layout, originalImage, resetImageAction(), and LayoutWidget::stopEdit(). Referenced by PhotoEditWidget().
00459 {
00460 //no changes? then just exit
00461 if(originalImage == NULL)
00462 {
00463 layout->stopEdit(true);
00464 return;
00465 }
00466
00467 //otherwise ask user if they are sure they want to permantly scare their photo :)
00468 QuestionDialog sure( "Keep changes?",
00469 "Once applied alterations cannot be undone.",
00470 "warning.png",
00471 this );
00472 //apply changes and exit
00473 if(sure.exec())
00474 {
00475 layout->stopEdit(true);
00476 }
00477 //revert before exiting
00478 else
00479 {
00480 resetImageAction();
00481 layout->stopEdit(true);
00482 }
00483 }
|
|
|
Sets the photo pointer.
Definition at line 140 of file photoEditWidget.cpp. References originalImage, photoDescriptionVal, photoView, resizeImage(), PhotoViewWidget::setPhoto(), SLIDESHOW_HEIGHT, and SLIDESHOW_WIDTH. Referenced by LayoutWidget::editPhoto().
00141 {
00142 //store photo object handle
00143 this->photo = photo;
00144
00145 //delete old original photo
00146 delete originalImage;
00147 originalImage = NULL;
00148
00149 //set description
00150 photoDescriptionVal->setText( photo->getDescription() );
00151
00152 //update view of photo
00153 photoView->setPhoto(photo);
00154
00155 //check to see if slideshow dimensions are known,
00156 //if not load image now and compute size, set
00157 //dimensions in photo object for future use
00158 if(photo->actualSlideshowWidth() == -1)
00159 {
00160 QImage *backendImage = new QImage( photo->getImageFilename() );
00161
00162 int w, h;
00163 resizeImage( backendImage->width(), backendImage->height(),
00164 SLIDESHOW_WIDTH, SLIDESHOW_HEIGHT,
00165 w, h);
00166 photo->setActualSlideshowDimensions( w, h);
00167 delete backendImage;
00168 backendImage = NULL;
00169 }
00170 }
|
|
|
Updates photo description.
Definition at line 172 of file photoEditWidget.cpp. References photo, and Photo::setDescription(). Referenced by PhotoEditWidget().
00173 {
00174 if(photo != NULL)
00175 photo->setDescription(val);
00176 }
|
|
|
"Adj. Exposure" button
Definition at line 107 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
|
|
"Adj. Exposure" image
Definition at line 104 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
|
|
Grid lower buttons are placed in.
Definition at line 82 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
|
|
"Crop" button
Definition at line 113 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
|
|
"Crop" image
Definition at line 110 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
|
|
Grid widgets are placed in.
Definition at line 79 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
|
|
Grid for lower buttons.
Definition at line 85 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
|
|
"Invert" button
Definition at line 119 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
|
|
"Invert" image
Definition at line 116 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
|
|
Pointer to the parent layout widget.
Definition at line 140 of file photoEditWidget.h. Referenced by PhotoEditWidget(), and returnFromEdit(). |
|
|
Backup of image before any manipulations were preformed, allows user to reset image.
Definition at line 98 of file photoEditWidget.h. Referenced by adjustExposure(), cropToRegion(), invertSelection(), PhotoEditWidget(), resetImageAction(), returnFromEdit(), setPhoto(), and ~PhotoEditWidget(). |
|
|
Pointer to backend photo.
Definition at line 94 of file photoEditWidget.h. Referenced by adjustExposure(), cropToRegion(), invertSelection(), PhotoEditWidget(), resetImageAction(), and updateDescription(). |
|
|
Label "Photo Description:".
Definition at line 88 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
|
|
Actual photo description.
Definition at line 91 of file photoEditWidget.h. Referenced by PhotoEditWidget(), and setPhoto(). |
|
|
Photo view, provides interface to see image and select regions of it.
Definition at line 101 of file photoEditWidget.h. Referenced by adjustExposure(), cropToRegion(), invertSelection(), PhotoEditWidget(), resetImageAction(), and setPhoto(). |
|
|
"Red Eye" button
Definition at line 125 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
|
|
"Red Eye" image
Definition at line 122 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
|
|
"Reset" button
Definition at line 131 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
|
|
"Reset" image
Definition at line 128 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
|
|
"Return" button
Definition at line 137 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
|
|
"Return" image
Definition at line 134 of file photoEditWidget.h. Referenced by PhotoEditWidget(). |
1.3.1