AlbumShaper
1.0a3
|
#include <histogramInterface.h>
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 |
int | maxBcount |
int | maxGRAYcount |
int | lumClick |
left and right bounds for each channel | |
int | lumDrag |
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. |
Definition at line 40 of file histogramInterface.h.
HistogramInterface::HistogramInterface | ( | QString | imageFilename, |
QWidget * | parent = 0 , |
||
const char * | name = 0 |
||
) |
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, LUMINOSITY, maxBcount, maxGcount, maxGRAYcount, maxRcount, NO_EFFECT, origImageSize, redVals, resetBoundaries(), scaleImage(), and selectAll().
: QWidget (parent, name, WNoAutoErase) { //set default mode to adjusted image displayedChannel = LUMINOSITY; //record original image width and height getImageSize( imageFilename, origImageSize ); //construct histogram for color and luminosity channels //resize image to current screen size for faster //scaling during resize events QRect screenSize = qApp->desktop()->availableGeometry(); QImage image; scaleImage( imageFilename, image, screenSize.width()/4, screenSize.height()/4 ); int i; for(i=0; i<256; i++) { redVals[i] = 0; greenVals[i] = 0; blueVals[i] = 0; grayVals[i] = 0; } int x, y; QRgb* rgb; uchar* scanLine; for( y=0; y<image.height(); y++) { scanLine = image.scanLine(y); for( x=0; x<image.width(); x++) { rgb = ((QRgb*)scanLine+x); redVals[ qRed(*rgb) ]++; greenVals[ qGreen(*rgb) ]++; blueVals[ qBlue(*rgb) ]++; grayVals[ qGray(*rgb) ]++; } //x } //y //find max r,g,b, and gray counts maxRcount = 0; maxGcount = 0; maxBcount = 0; maxGRAYcount = 0; for(i=0; i<256; i++) { if(redVals[i] > maxRcount) maxRcount = redVals[i]; if(greenVals[i] > maxGcount) maxGcount = greenVals[i]; if(blueVals[i] > maxBcount) maxBcount = blueVals[i]; if(grayVals[i] > maxGRAYcount) maxGRAYcount = grayVals[i]; } //---- //by default mouse drags have no effect dragMode = NO_EFFECT; currentMouseShape = NO_EFFECT; //watch mouse movements in order to drag selection setMouseTracking(true); //accept focus when clicked on setFocusPolicy( QWidget::ClickFocus ); QAccel *keyAccel = new QAccel( this ); keyAccel->connectItem( keyAccel->insertItem( CTRL + Key_A), this, SLOT(selectAll()) ); //default cursor is cross hair indication regions can be selected setCursor( getCursor(CROSS_CURSOR) ); //by default entire range is selected for all channels resetBoundaries(); }
HistogramInterface::~HistogramInterface | ( | ) |
double HistogramInterface::displayToIndex | ( | int | val | ) | [private] |
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().
{ return (255.0*coordinate) / ( width()-1 ); }
void HistogramInterface::getHistBoundaries | ( | int & | lumLeft, |
int & | lumRight, | ||
int & | redLeft, | ||
int & | redRight, | ||
int & | greenLeft, | ||
int & | greenRight, | ||
int & | blueLeft, | ||
int & | blueRight | ||
) |
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().
{ lumLeft = QMIN( lumClick, lumDrag ); lumRight = QMAX( lumClick, lumDrag ); redLeft = QMIN( redClick, redDrag ); redRight = QMAX( redClick, redDrag ); greenLeft = QMIN( greenClick, greenDrag ); greenRight = QMAX( greenClick, greenDrag ); blueLeft = QMIN( blueClick, blueDrag ); blueRight = QMAX( blueClick, blueDrag ); }
void HistogramInterface::getSelectedRange | ( | int & | left, |
int & | right | ||
) | [private] |
this utility function finds currently selected range
Definition at line 119 of file histogramInterface.cpp.
References BLUE, blueClick, blueDrag, displayedChannel, GREEN, greenClick, greenDrag, lumClick, lumDrag, LUMINOSITY, RED, redClick, and redDrag.
Referenced by mouseMoveEvent(), mousePressEvent(), nearBoundary(), paintEvent(), and selectAll().
{ if(displayedChannel == LUMINOSITY) { left = QMIN( lumClick, lumDrag ); right = QMAX( lumClick, lumDrag ); } else if(displayedChannel == RED) { left = QMIN( redClick, redDrag ); right = QMAX( redClick, redDrag ); } else if(displayedChannel == GREEN) { left = QMIN( greenClick, greenDrag ); right = QMAX( greenClick, greenDrag ); } else if(displayedChannel == BLUE) { left = QMIN( blueClick, blueDrag ); right = QMAX( blueClick, blueDrag ); } else { left = 0; right = 0; } }
int HistogramInterface::indexToDisplay | ( | int | val | ) | [private] |
converts index in 0-255 ranges to screen coordinate
Definition at line 150 of file histogramInterface.cpp.
References width.
Referenced by paintEvent().
{ return (index* (width()-1) ) / 255; }
QSize HistogramInterface::minimumSizeHint | ( | ) | const [virtual] |
Definition at line 286 of file histogramInterface.cpp.
References COLOR_BAR_BORDER, COLOR_BAR_HEIGHT, and COLOR_BAR_MARGIN.
{ return QSize( 256,100 + COLOR_BAR_MARGIN + 2*COLOR_BAR_BORDER + COLOR_BAR_HEIGHT ); }
void HistogramInterface::mouseMoveEvent | ( | QMouseEvent * | e | ) | [protected] |
Definition at line 368 of file histogramInterface.cpp.
References BLUE, blueDrag, CROSS_CURSOR, currentMouseShape, displayedChannel, displayToIndex(), DRAG, dragMode, getCursor(), getSelectedRange(), GREEN, greenDrag, lumDrag, LUMINOSITY, MOVE_HOR_CURSOR, nearBoundary(), NO_EFFECT, RED, redDrag, selectedRangeChanged(), and width.
{ //if not dragging a selection then update mouse cursor as appropriate if(dragMode == NO_EFFECT) { if( nearBoundary(e->pos()) && currentMouseShape == NO_EFFECT ) { currentMouseShape = DRAG; setCursor( getCursor(MOVE_HOR_CURSOR) ); } else if( !nearBoundary(e->pos()) && currentMouseShape == DRAG ) { currentMouseShape = NO_EFFECT; setCursor( getCursor(CROSS_CURSOR) ); } return; } //compute index in 0-255 range from mouse coordinates int x = QMAX( QMIN( e->pos().x(), width()-1 ), 0 ); int index = (int) displayToIndex( x ); //reset boundary if(displayedChannel == LUMINOSITY) { lumDrag = index; } else if(displayedChannel == RED) { redDrag = index; } else if(displayedChannel == GREEN) { greenDrag = index; } else if(displayedChannel == BLUE) { blueDrag = index; } //repaint repaint(false); //emit selectection changed signal int left, right; getSelectedRange( left, right ); emit selectedRangeChanged(); }
void HistogramInterface::mousePressEvent | ( | QMouseEvent * | e | ) | [protected] |
Definition at line 307 of file histogramInterface.cpp.
References blueClick, blueDrag, displayedChannel, displayToIndex(), DRAG, DRAG_THRESHOLD, dragMode, getSelectedRange(), GREEN, greenClick, greenDrag, lumClick, lumDrag, LUMINOSITY, RED, redClick, redDrag, and selectedRangeChanged().
{ //begin drag mode! dragMode = DRAG; //compute index from mouse position int index = (int) displayToIndex( e->pos().x() ); //get left and right to check for clicks near current boundaries int left, right; getSelectedRange( left, right ); //get click and drag handles int *click, *drag; if(displayedChannel == LUMINOSITY) { click = &lumClick; drag = &lumDrag; } else if(displayedChannel == RED) { click = &redClick; drag = &redDrag; } else if(displayedChannel == GREEN) { click = &greenClick; drag = &greenDrag; } else { click = &blueClick; drag = &blueDrag; } //if within threshold of left then start dragging that side if( index < left + DRAG_THRESHOLD && index > left - DRAG_THRESHOLD ) { *click = right; *drag = left; return; } //if within threshold of left then start dragging that side if( index < right + DRAG_THRESHOLD && index > right - DRAG_THRESHOLD ) { *click = left; *drag = right; return; } //else begin new drag else { *click = index; *drag = index; repaint(false); //emit selectection changed signal int left, right; getSelectedRange( left, right ); emit selectedRangeChanged(); } }
void HistogramInterface::mouseReleaseEvent | ( | QMouseEvent * | e | ) | [protected] |
Definition at line 406 of file histogramInterface.cpp.
References CROSS_CURSOR, currentMouseShape, DRAG, dragMode, getCursor(), nearBoundary(), and NO_EFFECT.
{ //set mouse drags to no longer have any effect on boundary dragMode = NO_EFFECT; //update mouse cursor if necessary if( !nearBoundary(e->pos()) && currentMouseShape == DRAG ) { currentMouseShape = NO_EFFECT; setCursor( getCursor(CROSS_CURSOR) ); } }
bool HistogramInterface::nearBoundary | ( | QPoint | p | ) | [private] |
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().
{ //compute index from mouse position int index = (int) displayToIndex( p.x() ); //get left and right to check for clicks near current boundaries int left, right; getSelectedRange( left, right ); //check if within threshold of left or right boundaries return ( (index < left + 1 + DRAG_THRESHOLD && index > left - DRAG_THRESHOLD) || (index < right + DRAG_THRESHOLD && index > right - 1 - DRAG_THRESHOLD) ); }
void HistogramInterface::paintEvent | ( | QPaintEvent * | e | ) | [protected] |
Definition at line 155 of file histogramInterface.cpp.
References b, BLUE, blueVals, buffer, COLOR_BAR_BORDER, COLOR_BAR_HEIGHT, COLOR_BAR_MARGIN, displayedChannel, displayToIndex(), getSelectedRange(), grayVals, GREEN, greenVals, HISTOGRAM_HEIGHT, indexToDisplay(), maxBcount, maxGcount, maxGRAYcount, maxRcount, RED, redVals, and width.
{ //create buffer to draw in QPixmap buffer( size() ); buffer.fill( white ); //create a painter pointing to the buffer QPainter bufferPainter( &buffer ); //turn off clipping to make painting operations faster bufferPainter.setClipping(false); //initialize buffer with background brush bufferPainter.fillRect( buffer.rect(), backgroundBrush() ); //get handle on histogram data, get max count, set default draw color, and find //left and right boundaries of current selection QColor color = black; int* data = grayVals; int maxCount = maxGRAYcount; if(displayedChannel == RED) { data = redVals; color = red; maxCount = maxRcount; } else if(displayedChannel == GREEN) { data = greenVals; color = green; maxCount = maxGcount; } else if(displayedChannel == BLUE) { data = blueVals; color = blue; maxCount = maxBcount; } int indexLeft, indexRight; getSelectedRange(indexLeft,indexRight); int displayLeft = indexToDisplay ( indexLeft ); int displayRight = indexToDisplay ( indexRight ); int histogramHeight = HISTOGRAM_HEIGHT; //iterate over each pixel column int x; for(x=0; x<width(); x++) { double index = displayToIndex( x ); int indexL = (int)index; double scaleR = index - indexL; int h = 0; if(indexL < 255) { h = (int) ((1-scaleR)*data[indexL] + scaleR*data[indexL+1]); } else { h = data[255]; } //scale count so that the maxCount maps to the maximum height double scaledH = (histogramHeight*h)/maxCount; h = (int) scaledH; //round up values between 0 and 1 so show data is there if( h == 0 && scaledH > h) h++; if(h > 0) { //use a gray color outside selected range QColor usedColor = color; if(x < displayLeft || x > displayRight) { usedColor = gray; } bufferPainter.fillRect( QRect(x, histogramHeight - h, 1, h), QBrush(usedColor) ); } //if this is left or right boundary of selection and entire range not selected then //draw a vertical black line to make it stand out more if( (x == displayLeft || x == displayLeft+1 || x == displayRight || x == displayRight-1) ) { bufferPainter.drawLine( x, 0, x, histogramHeight-1 ); } } //---- //paint color bar key below //first a black border bufferPainter.fillRect( QRect(0, histogramHeight + COLOR_BAR_MARGIN, width(), COLOR_BAR_HEIGHT+2*COLOR_BAR_BORDER), QBrush(black) ); //next the color gradient QColor scaledColor; for(x=COLOR_BAR_BORDER; x < width()-COLOR_BAR_BORDER; x++) { int index; if(x <= displayLeft ) index = 0; else if(x >= displayRight) index = 255; else index = (int) (255.0*(x-displayLeft))/(displayRight - displayLeft); int r = color.red(); int g = color.green(); int b = color.blue(); if( r != 0) r = index; if( g != 0) g = index; if( b != 0) b = index; //black color was used when adjusting luminance, scale to white instead (since black is 0) if( color == black ) { r = g = b = index; } scaledColor.setRgb( r,g,b ); bufferPainter.fillRect( QRect(x, histogramHeight + COLOR_BAR_MARGIN + COLOR_BAR_BORDER, 1, COLOR_BAR_HEIGHT), QBrush(scaledColor) ); } //end painter bufferPainter.end(); //blit buffer to screen bitBlt( this, e->rect().x(), e->rect().y(), &buffer, e->rect().x(), e->rect().y(), e->rect().width(), e->rect().height() ); }
void HistogramInterface::resetBoundaries | ( | ) |
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().
{ lumClick = redClick = greenClick = blueClick = 0; lumDrag = redDrag = greenDrag = blueDrag = 255; repaint(false); emit selectedRangeChanged(); }
void HistogramInterface::resizeEvent | ( | QResizeEvent * | ) | [protected] |
Definition at line 114 of file histogramInterface.cpp.
{
repaint(false);
}
void HistogramInterface::selectAll | ( | ) | [private, slot] |
Definition at line 419 of file histogramInterface.cpp.
References BLUE, blueClick, blueDrag, displayedChannel, getSelectedRange(), GREEN, greenClick, greenDrag, lumClick, lumDrag, LUMINOSITY, RED, redClick, redDrag, and selectedRangeChanged().
Referenced by HistogramInterface().
{ //reset boundary if(displayedChannel == LUMINOSITY) { lumClick = 0, lumDrag = 255; } else if(displayedChannel == RED) { redClick = 0; redDrag = 255; } else if(displayedChannel == GREEN) { greenClick = 0; greenDrag = 255; } else if(displayedChannel == BLUE) { blueClick = 0; blueDrag = 255; } repaint(false); //emit selectection changed signal int left, right; getSelectedRange( left, right ); emit selectedRangeChanged(); }
void HistogramInterface::selectedRangeChanged | ( | ) | [signal] |
Referenced by mouseMoveEvent(), mousePressEvent(), resetBoundaries(), and selectAll().
void HistogramInterface::setDisplayChannel | ( | DISPLAYED_CHANNEL | channel | ) |
Sets currently displayed channel.
Definition at line 279 of file histogramInterface.cpp.
References displayedChannel.
Referenced by HistogramEditor::selectHistogramType().
{ //set mode and repaint displayedChannel = channel; repaint(false); }
int HistogramInterface::blueClick [private] |
Definition at line 110 of file histogramInterface.h.
Referenced by getHistBoundaries(), getSelectedRange(), mousePressEvent(), resetBoundaries(), and selectAll().
int HistogramInterface::blueDrag [private] |
Definition at line 110 of file histogramInterface.h.
Referenced by getHistBoundaries(), getSelectedRange(), mouseMoveEvent(), mousePressEvent(), resetBoundaries(), and selectAll().
int HistogramInterface::blueVals[256] [private] |
Definition at line 100 of file histogramInterface.h.
Referenced by HistogramInterface(), and paintEvent().
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().
DRAG_MODE HistogramInterface::dragMode [private] |
effect of mouse drags
Definition at line 116 of file histogramInterface.h.
Referenced by HistogramInterface(), mouseMoveEvent(), mousePressEvent(), and mouseReleaseEvent().
int HistogramInterface::grayVals[256] [private] |
Definition at line 101 of file histogramInterface.h.
Referenced by HistogramInterface(), and paintEvent().
int HistogramInterface::greenClick [private] |
Definition at line 109 of file histogramInterface.h.
Referenced by getHistBoundaries(), getSelectedRange(), mousePressEvent(), resetBoundaries(), and selectAll().
int HistogramInterface::greenDrag [private] |
Definition at line 109 of file histogramInterface.h.
Referenced by getHistBoundaries(), getSelectedRange(), mouseMoveEvent(), mousePressEvent(), resetBoundaries(), and selectAll().
int HistogramInterface::greenVals[256] [private] |
Definition at line 99 of file histogramInterface.h.
Referenced by HistogramInterface(), and paintEvent().
int HistogramInterface::lumClick [private] |
left and right bounds for each channel
Definition at line 107 of file histogramInterface.h.
Referenced by getHistBoundaries(), getSelectedRange(), mousePressEvent(), resetBoundaries(), and selectAll().
int HistogramInterface::lumDrag [private] |
Definition at line 107 of file histogramInterface.h.
Referenced by getHistBoundaries(), getSelectedRange(), mouseMoveEvent(), mousePressEvent(), resetBoundaries(), and selectAll().
int HistogramInterface::maxBcount [private] |
Definition at line 104 of file histogramInterface.h.
Referenced by HistogramInterface(), and paintEvent().
int HistogramInterface::maxGcount [private] |
Definition at line 104 of file histogramInterface.h.
Referenced by HistogramInterface(), and paintEvent().
int HistogramInterface::maxGRAYcount [private] |
Definition at line 104 of file histogramInterface.h.
Referenced by HistogramInterface(), and paintEvent().
int HistogramInterface::maxRcount [private] |
max r,g,b, and gray counts
Definition at line 104 of file histogramInterface.h.
Referenced by HistogramInterface(), and paintEvent().
QSize HistogramInterface::origImageSize [private] |
original image dimensions, needed for painting
Definition at line 113 of file histogramInterface.h.
Referenced by HistogramInterface().
int HistogramInterface::redClick [private] |
Definition at line 108 of file histogramInterface.h.
Referenced by getHistBoundaries(), getSelectedRange(), mousePressEvent(), resetBoundaries(), and selectAll().
int HistogramInterface::redDrag [private] |
Definition at line 108 of file histogramInterface.h.
Referenced by getHistBoundaries(), getSelectedRange(), mouseMoveEvent(), mousePressEvent(), resetBoundaries(), and selectAll().
int HistogramInterface::redVals[256] [private] |
color and luminosity histograms
Definition at line 98 of file histogramInterface.h.
Referenced by HistogramInterface(), and paintEvent().