#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(). |