#include <histogramInterface.h>
Inheritance diagram for HistogramInterface:
Signals | |
void | selectedRangeChanged () |
Public Member Functions | |
HistogramInterface (QString imageFilename, QWidget *parent=0, const char *name=0) | |
Creates layout. | |
~HistogramInterface () | |
Deletes objects. | |
void | setDisplayChannel (DISPLAYED_CHANNEL channel) |
Sets currently displayed channel. | |
virtual QSize | minimumSizeHint () const |
void | getHistBoundaries (int &lumLeft, int &lumRight, int &redLeft, int &redRight, int &greenLeft, int &greenRight, int &blueLeft, int &blueRight) |
returns histogram boundaries | |
void | resetBoundaries () |
resets all boundaries | |
Protected Member Functions | |
void | paintEvent (QPaintEvent *e) |
void | resizeEvent (QResizeEvent *) |
void | mousePressEvent (QMouseEvent *e) |
void | mouseReleaseEvent (QMouseEvent *) |
void | mouseMoveEvent (QMouseEvent *e) |
Private Slots | |
void | selectAll () |
Private Member Functions | |
void | getSelectedRange (int &left, int &right) |
this utility function finds currently selected range | |
double | displayToIndex (int val) |
convert screen coordinate to index in 0-255 range | |
int | indexToDisplay (int val) |
converts index in 0-255 ranges to screen coordinate | |
bool | nearBoundary (QPoint p) |
determines if mouse is near boundary | |
Private Attributes | |
DISPLAYED_CHANNEL | displayedChannel |
Currently displayed channel. | |
int | redVals [256] |
color and luminosity histograms | |
int | greenVals [256] |
int | blueVals [256] |
int | grayVals [256] |
int | maxRcount |
max r,g,b, and gray counts | |
int | maxGcount |
max r,g,b, and gray counts | |
int | maxBcount |
max r,g,b, and gray counts | |
int | maxGRAYcount |
max r,g,b, and gray counts | |
int | lumClick |
left and right bounds for each channel | |
int | lumDrag |
left and right bounds for each channel | |
int | redClick |
int | redDrag |
int | greenClick |
int | greenDrag |
int | blueClick |
int | blueDrag |
QSize | origImageSize |
original image dimensions, needed for painting | |
DRAG_MODE | dragMode |
effect of mouse drags | |
DRAG_MODE | currentMouseShape |
current mouse shape. |
|
Creates layout. add keybinding for selecting entire range Definition at line 36 of file histogramInterface.cpp. References blueVals, CROSS_CURSOR, currentMouseShape, displayedChannel, dragMode, getCursor(), getImageSize(), grayVals, greenVals, maxBcount, maxGcount, maxGRAYcount, maxRcount, origImageSize, redVals, resetBoundaries(), scaleImage(), and selectAll(). 00037 : 00038 QWidget (parent, name, WNoAutoErase) 00039 { 00040 //set default mode to adjusted image 00041 displayedChannel = LUMINOSITY; 00042 00043 //record original image width and height 00044 getImageSize( imageFilename, origImageSize ); 00045 00046 //construct histogram for color and luminosity channels 00047 //resize image to current screen size for faster 00048 //scaling during resize events 00049 QRect screenSize = qApp->desktop()->availableGeometry(); 00050 QImage image; 00051 scaleImage( imageFilename, image, screenSize.width()/4, screenSize.height()/4 ); 00052 00053 int i; 00054 for(i=0; i<256; i++) 00055 { 00056 redVals[i] = 0; 00057 greenVals[i] = 0; 00058 blueVals[i] = 0; 00059 grayVals[i] = 0; 00060 } 00061 int x, y; 00062 QRgb* rgb; 00063 uchar* scanLine; 00064 for( y=0; y<image.height(); y++) 00065 { 00066 scanLine = image.scanLine(y); 00067 for( x=0; x<image.width(); x++) 00068 { 00069 rgb = ((QRgb*)scanLine+x); 00070 redVals[ qRed(*rgb) ]++; 00071 greenVals[ qGreen(*rgb) ]++; 00072 blueVals[ qBlue(*rgb) ]++; 00073 grayVals[ qGray(*rgb) ]++; 00074 } //x 00075 } //y 00076 00077 //find max r,g,b, and gray counts 00078 maxRcount = 0; 00079 maxGcount = 0; 00080 maxBcount = 0; 00081 maxGRAYcount = 0; 00082 for(i=0; i<256; i++) 00083 { 00084 if(redVals[i] > maxRcount) maxRcount = redVals[i]; 00085 if(greenVals[i] > maxGcount) maxGcount = greenVals[i]; 00086 if(blueVals[i] > maxBcount) maxBcount = blueVals[i]; 00087 if(grayVals[i] > maxGRAYcount) maxGRAYcount = grayVals[i]; 00088 } 00089 //---- 00090 //by default mouse drags have no effect 00091 dragMode = NO_EFFECT; 00092 currentMouseShape = NO_EFFECT; 00093 00094 //watch mouse movements in order to drag selection 00095 setMouseTracking(true); 00096 00097 //accept focus when clicked on 00098 setFocusPolicy( QWidget::ClickFocus ); 00099 00101 QAccel *keyAccel = new QAccel( this ); 00102 keyAccel->connectItem( keyAccel->insertItem( CTRL + Key_A), 00103 this, SLOT(selectAll()) ); 00104 00105 //default cursor is cross hair indication regions can be selected 00106 setCursor( getCursor(CROSS_CURSOR) ); 00107 00108 //by default entire range is selected for all channels 00109 resetBoundaries(); 00110 }
|
|
Deletes objects.
Definition at line 112 of file histogramInterface.cpp. 00112 { }
|
|
convert screen coordinate to index in 0-255 range
Definition at line 145 of file histogramInterface.cpp. References width. Referenced by mouseMoveEvent(), mousePressEvent(), nearBoundary(), and paintEvent(). 00146 { 00147 return (255.0*coordinate) / ( width()-1 ); 00148 }
|
|
returns histogram boundaries
Definition at line 434 of file histogramInterface.cpp. References blueClick, blueDrag, greenClick, greenDrag, lumClick, lumDrag, redClick, and redDrag. Referenced by HistogramEditor::adjustImage(), HistogramEditor::applyAction(), and HistogramEditor::getHistBoundaries(). 00438 { 00439 lumLeft = QMIN( lumClick, lumDrag ); 00440 lumRight = QMAX( lumClick, lumDrag ); 00441 00442 redLeft = QMIN( redClick, redDrag ); 00443 redRight = QMAX( redClick, redDrag ); 00444 00445 greenLeft = QMIN( greenClick, greenDrag ); 00446 greenRight = QMAX( greenClick, greenDrag ); 00447 00448 blueLeft = QMIN( blueClick, blueDrag ); 00449 blueRight = QMAX( blueClick, blueDrag ); 00450 }
|
|
this utility function finds currently selected range
Definition at line 119 of file histogramInterface.cpp. References blueClick, blueDrag, displayedChannel, greenClick, greenDrag, lumClick, lumDrag, redClick, and redDrag. Referenced by mouseMoveEvent(), mousePressEvent(), nearBoundary(), paintEvent(), and selectAll(). 00120 { 00121 if(displayedChannel == LUMINOSITY) 00122 { 00123 left = QMIN( lumClick, lumDrag ); 00124 right = QMAX( lumClick, lumDrag ); 00125 } 00126 else if(displayedChannel == RED) 00127 { 00128 left = QMIN( redClick, redDrag ); 00129 right = QMAX( redClick, redDrag ); 00130 } 00131 else if(displayedChannel == GREEN) 00132 { 00133 left = QMIN( greenClick, greenDrag ); 00134 right = QMAX( greenClick, greenDrag ); 00135 } 00136 else if(displayedChannel == BLUE) 00137 { 00138 left = QMIN( blueClick, blueDrag ); 00139 right = QMAX( blueClick, blueDrag ); 00140 } 00141 else 00142 { left = 0; right = 0; } 00143 }
|
|
converts index in 0-255 ranges to screen coordinate
Definition at line 150 of file histogramInterface.cpp. References width. Referenced by paintEvent(). 00151 { 00152 return (index* (width()-1) ) / 255; 00153 }
|
|
Definition at line 286 of file histogramInterface.cpp. References COLOR_BAR_BORDER, COLOR_BAR_HEIGHT, and COLOR_BAR_MARGIN. 00287 {
00288 return QSize( 256,100 + COLOR_BAR_MARGIN + 2*COLOR_BAR_BORDER + COLOR_BAR_HEIGHT );
00289 }
|
|
Definition at line 368 of file histogramInterface.cpp. References blueDrag, CROSS_CURSOR, currentMouseShape, displayedChannel, displayToIndex(), dragMode, getCursor(), getSelectedRange(), greenDrag, lumDrag, MOVE_HOR_CURSOR, nearBoundary(), redDrag, selectedRangeChanged(), and width. 00369 { 00370 //if not dragging a selection then update mouse cursor as appropriate 00371 if(dragMode == NO_EFFECT) 00372 { 00373 if( nearBoundary(e->pos()) && currentMouseShape == NO_EFFECT ) 00374 { 00375 currentMouseShape = DRAG; 00376 setCursor( getCursor(MOVE_HOR_CURSOR) ); 00377 } 00378 else if( !nearBoundary(e->pos()) && currentMouseShape == DRAG ) 00379 { 00380 currentMouseShape = NO_EFFECT; 00381 setCursor( getCursor(CROSS_CURSOR) ); 00382 } 00383 00384 return; 00385 } 00386 00387 //compute index in 0-255 range from mouse coordinates 00388 int x = QMAX( QMIN( e->pos().x(), width()-1 ), 0 ); 00389 int index = (int) displayToIndex( x ); 00390 00391 //reset boundary 00392 if(displayedChannel == LUMINOSITY) { lumDrag = index; } 00393 else if(displayedChannel == RED) { redDrag = index; } 00394 else if(displayedChannel == GREEN) { greenDrag = index; } 00395 else if(displayedChannel == BLUE) { blueDrag = index; } 00396 00397 //repaint 00398 repaint(false); 00399 00400 //emit selectection changed signal 00401 int left, right; 00402 getSelectedRange( left, right ); 00403 emit selectedRangeChanged(); 00404 }
|
|
Definition at line 307 of file histogramInterface.cpp. References displayedChannel, displayToIndex(), DRAG_THRESHOLD, dragMode, getSelectedRange(), and selectedRangeChanged(). 00308 { 00309 //begin drag mode! 00310 dragMode = DRAG; 00311 00312 //compute index from mouse position 00313 int index = (int) displayToIndex( e->pos().x() ); 00314 00315 //get left and right to check for clicks near current boundaries 00316 int left, right; 00317 getSelectedRange( left, right ); 00318 00319 //get click and drag handles 00320 int *click, *drag; 00321 if(displayedChannel == LUMINOSITY) 00322 { 00323 click = &lumClick; drag = &lumDrag; 00324 } 00325 else if(displayedChannel == RED) 00326 { 00327 click = &redClick; drag = &redDrag; 00328 } 00329 else if(displayedChannel == GREEN) 00330 { 00331 click = &greenClick; drag = &greenDrag; 00332 } 00333 else 00334 { 00335 click = &blueClick; drag = &blueDrag; 00336 } 00337 00338 //if within threshold of left then start dragging that side 00339 if( index < left + DRAG_THRESHOLD && 00340 index > left - DRAG_THRESHOLD ) 00341 { 00342 *click = right; 00343 *drag = left; 00344 return; 00345 } 00346 //if within threshold of left then start dragging that side 00347 if( index < right + DRAG_THRESHOLD && 00348 index > right - DRAG_THRESHOLD ) 00349 { 00350 *click = left; 00351 *drag = right; 00352 return; 00353 } 00354 //else begin new drag 00355 else 00356 { 00357 *click = index; 00358 *drag = index; 00359 repaint(false); 00360 00361 //emit selectection changed signal 00362 int left, right; 00363 getSelectedRange( left, right ); 00364 emit selectedRangeChanged(); 00365 } 00366 }
|
|
Definition at line 406 of file histogramInterface.cpp. References CROSS_CURSOR, currentMouseShape, dragMode, getCursor(), and nearBoundary(). 00407 { 00408 //set mouse drags to no longer have any effect on boundary 00409 dragMode = NO_EFFECT; 00410 00411 //update mouse cursor if necessary 00412 if( !nearBoundary(e->pos()) && currentMouseShape == DRAG ) 00413 { 00414 currentMouseShape = NO_EFFECT; 00415 setCursor( getCursor(CROSS_CURSOR) ); 00416 } 00417 }
|
|
determines if mouse is near boundary
Definition at line 291 of file histogramInterface.cpp. References displayToIndex(), DRAG_THRESHOLD, and getSelectedRange(). Referenced by mouseMoveEvent(), and mouseReleaseEvent(). 00292 { 00293 //compute index from mouse position 00294 int index = (int) displayToIndex( p.x() ); 00295 00296 //get left and right to check for clicks near current boundaries 00297 int left, right; 00298 getSelectedRange( left, right ); 00299 00300 //check if within threshold of left or right boundaries 00301 return ( (index < left + 1 + DRAG_THRESHOLD && 00302 index > left - DRAG_THRESHOLD) || 00303 (index < right + DRAG_THRESHOLD && 00304 index > right - 1 - DRAG_THRESHOLD) ); 00305 }
|
|
Definition at line 155 of file histogramInterface.cpp. References b, buffer, COLOR_BAR_BORDER, COLOR_BAR_HEIGHT, COLOR_BAR_MARGIN, displayedChannel, displayToIndex(), getSelectedRange(), indexToDisplay(), and width. 00156 { 00157 //create buffer to draw in 00158 QPixmap buffer( size() ); 00159 buffer.fill( white ); 00160 00161 //create a painter pointing to the buffer 00162 QPainter bufferPainter( &buffer ); 00163 00164 //turn off clipping to make painting operations faster 00165 bufferPainter.setClipping(false); 00166 00167 //initialize buffer with background brush 00168 bufferPainter.fillRect( buffer.rect(), backgroundBrush() ); 00169 00170 //get handle on histogram data, get max count, set default draw color, and find 00171 //left and right boundaries of current selection 00172 QColor color = black; 00173 int* data = grayVals; 00174 int maxCount = maxGRAYcount; 00175 00176 if(displayedChannel == RED) { data = redVals; color = red; maxCount = maxRcount; } 00177 else if(displayedChannel == GREEN) { data = greenVals; color = green; maxCount = maxGcount; } 00178 else if(displayedChannel == BLUE) { data = blueVals; color = blue; maxCount = maxBcount; } 00179 00180 int indexLeft, indexRight; 00181 getSelectedRange(indexLeft,indexRight); 00182 int displayLeft = indexToDisplay ( indexLeft ); 00183 int displayRight = indexToDisplay ( indexRight ); 00184 00185 int histogramHeight = HISTOGRAM_HEIGHT; 00186 00187 //iterate over each pixel column 00188 int x; 00189 for(x=0; x<width(); x++) 00190 { 00191 double index = displayToIndex( x ); 00192 int indexL = (int)index; 00193 double scaleR = index - indexL; 00194 00195 int h = 0; 00196 if(indexL < 255) 00197 { 00198 h = (int) ((1-scaleR)*data[indexL] + scaleR*data[indexL+1]); 00199 } 00200 else 00201 { 00202 h = data[255]; 00203 } 00204 00205 //scale count so that the maxCount maps to the maximum height 00206 double scaledH = (histogramHeight*h)/maxCount; 00207 h = (int) scaledH; 00208 //round up values between 0 and 1 so show data is there 00209 if( h == 0 && scaledH > h) h++; 00210 00211 if(h > 0) 00212 { 00213 //use a gray color outside selected range 00214 QColor usedColor = color; 00215 if(x < displayLeft || x > displayRight) { usedColor = gray; } 00216 00217 bufferPainter.fillRect( QRect(x, histogramHeight - h, 00218 1, h), 00219 QBrush(usedColor) ); 00220 } 00221 00222 //if this is left or right boundary of selection and entire range not selected then 00223 //draw a vertical black line to make it stand out more 00224 if( (x == displayLeft || x == displayLeft+1 || 00225 x == displayRight || x == displayRight-1) ) 00226 { 00227 bufferPainter.drawLine( x, 0, x, histogramHeight-1 ); 00228 } 00229 } 00230 //---- 00231 //paint color bar key below 00232 00233 //first a black border 00234 bufferPainter.fillRect( QRect(0, histogramHeight + COLOR_BAR_MARGIN, 00235 width(), COLOR_BAR_HEIGHT+2*COLOR_BAR_BORDER), 00236 QBrush(black) ); 00237 00238 //next the color gradient 00239 QColor scaledColor; 00240 for(x=COLOR_BAR_BORDER; x < width()-COLOR_BAR_BORDER; x++) 00241 { 00242 int index; 00243 if(x <= displayLeft ) 00244 index = 0; 00245 else if(x >= displayRight) 00246 index = 255; 00247 else 00248 index = (int) (255.0*(x-displayLeft))/(displayRight - displayLeft); 00249 00250 int r = color.red(); 00251 int g = color.green(); 00252 int b = color.blue(); 00253 00254 if( r != 0) r = index; 00255 if( g != 0) g = index; 00256 if( b != 0) b = index; 00257 00258 //black color was used when adjusting luminance, scale to white instead (since black is 0) 00259 if( color == black ) 00260 { r = g = b = index; } 00261 00262 scaledColor.setRgb( r,g,b ); 00263 bufferPainter.fillRect( QRect(x, histogramHeight + COLOR_BAR_MARGIN + COLOR_BAR_BORDER, 00264 1, COLOR_BAR_HEIGHT), 00265 QBrush(scaledColor) ); 00266 } 00267 00268 //end painter 00269 bufferPainter.end(); 00270 00271 //blit buffer to screen 00272 bitBlt( this, 00273 e->rect().x(), e->rect().y(), 00274 &buffer, 00275 e->rect().x(), e->rect().y(), 00276 e->rect().width(), e->rect().height() ); 00277 }
|
|
resets all boundaries
Definition at line 452 of file histogramInterface.cpp. References blueClick, blueDrag, greenClick, greenDrag, lumClick, lumDrag, redClick, redDrag, and selectedRangeChanged(). Referenced by HistogramInterface(), and HistogramEditor::resetAction(). 00453 { 00454 lumClick = redClick = greenClick = blueClick = 0; 00455 lumDrag = redDrag = greenDrag = blueDrag = 255; 00456 repaint(false); 00457 emit selectedRangeChanged(); 00458 }
|
|
Definition at line 114 of file histogramInterface.cpp. 00115 {
00116 repaint(false);
00117 }
|
|
Definition at line 419 of file histogramInterface.cpp. References blueClick, blueDrag, displayedChannel, getSelectedRange(), greenClick, greenDrag, lumClick, lumDrag, redClick, redDrag, and selectedRangeChanged(). Referenced by HistogramInterface(). 00420 { 00421 //reset boundary 00422 if(displayedChannel == LUMINOSITY) { lumClick = 0, lumDrag = 255; } 00423 else if(displayedChannel == RED) { redClick = 0; redDrag = 255; } 00424 else if(displayedChannel == GREEN) { greenClick = 0; greenDrag = 255; } 00425 else if(displayedChannel == BLUE) { blueClick = 0; blueDrag = 255; } 00426 repaint(false); 00427 00428 //emit selectection changed signal 00429 int left, right; 00430 getSelectedRange( left, right ); 00431 emit selectedRangeChanged(); 00432 }
|
|
Referenced by mouseMoveEvent(), mousePressEvent(), resetBoundaries(), and selectAll(). |
|
Sets currently displayed channel.
Definition at line 279 of file histogramInterface.cpp. References displayedChannel. Referenced by HistogramEditor::selectHistogramType(). 00280 { 00281 //set mode and repaint 00282 displayedChannel = channel; 00283 repaint(false); 00284 }
|
|
Definition at line 110 of file histogramInterface.h. Referenced by getHistBoundaries(), getSelectedRange(), resetBoundaries(), and selectAll(). |
|
Definition at line 110 of file histogramInterface.h. Referenced by getHistBoundaries(), getSelectedRange(), mouseMoveEvent(), resetBoundaries(), and selectAll(). |
|
Definition at line 100 of file histogramInterface.h. Referenced by HistogramInterface(). |
|
current mouse shape. by caching this value we avoid resetting the mouse cursor every time it moves etc. Definition at line 120 of file histogramInterface.h. Referenced by HistogramInterface(), mouseMoveEvent(), and mouseReleaseEvent(). |
|
Currently displayed channel.
Definition at line 95 of file histogramInterface.h. Referenced by getSelectedRange(), HistogramInterface(), mouseMoveEvent(), mousePressEvent(), paintEvent(), selectAll(), and setDisplayChannel(). |
|
effect of mouse drags
Definition at line 116 of file histogramInterface.h. Referenced by HistogramInterface(), mouseMoveEvent(), mousePressEvent(), and mouseReleaseEvent(). |
|
Definition at line 101 of file histogramInterface.h. Referenced by HistogramInterface(). |
|
Definition at line 109 of file histogramInterface.h. Referenced by getHistBoundaries(), getSelectedRange(), resetBoundaries(), and selectAll(). |
|
Definition at line 109 of file histogramInterface.h. Referenced by getHistBoundaries(), getSelectedRange(), mouseMoveEvent(), resetBoundaries(), and selectAll(). |
|
Definition at line 99 of file histogramInterface.h. Referenced by HistogramInterface(). |
|
left and right bounds for each channel
Definition at line 107 of file histogramInterface.h. Referenced by getHistBoundaries(), getSelectedRange(), resetBoundaries(), and selectAll(). |
|
left and right bounds for each channel
Definition at line 107 of file histogramInterface.h. Referenced by getHistBoundaries(), getSelectedRange(), mouseMoveEvent(), resetBoundaries(), and selectAll(). |
|
max r,g,b, and gray counts
Definition at line 104 of file histogramInterface.h. Referenced by HistogramInterface(). |
|
max r,g,b, and gray counts
Definition at line 104 of file histogramInterface.h. Referenced by HistogramInterface(). |
|
max r,g,b, and gray counts
Definition at line 104 of file histogramInterface.h. Referenced by HistogramInterface(). |
|
max r,g,b, and gray counts
Definition at line 104 of file histogramInterface.h. Referenced by HistogramInterface(). |
|
original image dimensions, needed for painting
Definition at line 113 of file histogramInterface.h. Referenced by HistogramInterface(). |
|
Definition at line 108 of file histogramInterface.h. Referenced by getHistBoundaries(), getSelectedRange(), resetBoundaries(), and selectAll(). |
|
Definition at line 108 of file histogramInterface.h. Referenced by getHistBoundaries(), getSelectedRange(), mouseMoveEvent(), resetBoundaries(), and selectAll(). |
|
color and luminosity histograms
Definition at line 98 of file histogramInterface.h. Referenced by HistogramInterface(). |