AlbumShaper 1.0a3
HistogramInterface Class Reference

#include <histogramInterface.h>

Inheritance diagram for HistogramInterface:
Collaboration 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
 
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.
 

Detailed Description

Definition at line 44 of file histogramInterface.h.

Constructor & Destructor Documentation

◆ HistogramInterface()

HistogramInterface::HistogramInterface ( QString imageFilename,
QWidget * parent = 0,
const char * name = 0 )

Creates layout.

add keybinding for selecting entire range

Definition at line 41 of file histogramInterface.cpp.

42 :
43 QWidget (parent, name, Qt::WNoAutoErase)
44{
45 //set default mode to adjusted image
47
48 //record original image width and height
49 getImageSize( imageFilename, origImageSize );
50
51 //construct histogram for color and luminosity channels
52 //resize image to current screen size for faster
53 //scaling during resize events
54 QRect screenSize = qApp->desktop()->availableGeometry();
55 QImage image;
56 scaleImage( imageFilename, image, screenSize.width()/4, screenSize.height()/4 );
57
58 int i;
59 for(i=0; i<256; i++)
60 {
61 redVals[i] = 0;
62 greenVals[i] = 0;
63 blueVals[i] = 0;
64 grayVals[i] = 0;
65 }
66 int x, y;
67 QRgb* rgb;
68 uchar* scanLine;
69 for( y=0; y<image.height(); y++)
70 {
71 scanLine = image.scanLine(y);
72 for( x=0; x<image.width(); x++)
73 {
74 rgb = ((QRgb*)scanLine+x);
75 redVals[ qRed(*rgb) ]++;
76 greenVals[ qGreen(*rgb) ]++;
77 blueVals[ qBlue(*rgb) ]++;
78 grayVals[ qGray(*rgb) ]++;
79 } //x
80 } //y
81
82 //find max r,g,b, and gray counts
83 maxRcount = 0;
84 maxGcount = 0;
85 maxBcount = 0;
86 maxGRAYcount = 0;
87 for(i=0; i<256; i++)
88 {
89 if(redVals[i] > maxRcount) maxRcount = redVals[i];
91 if(blueVals[i] > maxBcount) maxBcount = blueVals[i];
93 }
94 //----
95 //by default mouse drags have no effect
98
99 //watch mouse movements in order to drag selection
100 setMouseTracking(true);
101
102 //accept focus when clicked on
103 setFocusPolicy( Qt::ClickFocus );
104
106 Q3Accel *keyAccel = new Q3Accel( this );
107 keyAccel->connectItem( keyAccel->insertItem( Qt::CTRL + Qt::Key_A),
108 this, SLOT(selectAll()) );
109
110 //default cursor is cross hair indication regions can be selected
111 setCursor( getCursor(CROSS_CURSOR) );
112
113 //by default entire range is selected for all channels
115}
DISPLAYED_CHANNEL displayedChannel
Currently displayed channel.
int redVals[256]
color and luminosity histograms
QSize origImageSize
original image dimensions, needed for painting
DRAG_MODE dragMode
effect of mouse drags
DRAG_MODE currentMouseShape
current mouse shape.
void resetBoundaries()
resets all boundaries
int maxRcount
max r,g,b, and gray counts
const QCursor & getCursor(CUSTOM_CURSOR_TYPE type)
Definition cursors.cpp:52
@ CROSS_CURSOR
Definition cursors.h:17
@ LUMINOSITY
@ NO_EFFECT
bool scaleImage(QString fileIn, QString fileOut, int newWidth, int newHeight)
Scale image and save copy to disk.
bool getImageSize(const char *filename, QSize &size)
Get image dimensions.

References blueVals, CROSS_CURSOR, currentMouseShape, displayedChannel, dragMode, getCursor(), getImageSize(), grayVals, greenVals, LUMINOSITY, maxBcount, maxGcount, maxGRAYcount, maxRcount, NO_EFFECT, origImageSize, redVals, resetBoundaries(), scaleImage(), and selectAll().

◆ ~HistogramInterface()

HistogramInterface::~HistogramInterface ( )

Deletes objects.

Definition at line 117 of file histogramInterface.cpp.

117{ }

Member Function Documentation

◆ displayToIndex()

double HistogramInterface::displayToIndex ( int val)
private

convert screen coordinate to index in 0-255 range

Definition at line 150 of file histogramInterface.cpp.

151{
152 return (255.0*coordinate) / ( width()-1 );
153}
int width
Definition blur.cpp:79

References width.

Referenced by mouseMoveEvent(), mousePressEvent(), nearBoundary(), and paintEvent().

◆ getHistBoundaries()

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 439 of file histogramInterface.cpp.

443{
444 lumLeft = QMIN( lumClick, lumDrag );
445 lumRight = QMAX( lumClick, lumDrag );
446
447 redLeft = QMIN( redClick, redDrag );
448 redRight = QMAX( redClick, redDrag );
449
450 greenLeft = QMIN( greenClick, greenDrag );
451 greenRight = QMAX( greenClick, greenDrag );
452
453 blueLeft = QMIN( blueClick, blueDrag );
454 blueRight = QMAX( blueClick, blueDrag );
455}
int lumClick
left and right bounds for each channel

References blueClick, blueDrag, greenClick, greenDrag, lumClick, lumDrag, redClick, and redDrag.

Referenced by HistogramEditor::adjustImage(), HistogramEditor::applyAction(), and HistogramEditor::getHistBoundaries().

◆ getSelectedRange()

void HistogramInterface::getSelectedRange ( int & left,
int & right )
private

this utility function finds currently selected range

Definition at line 124 of file histogramInterface.cpp.

125{
127 {
128 left = QMIN( lumClick, lumDrag );
129 right = QMAX( lumClick, lumDrag );
130 }
131 else if(displayedChannel == RED)
132 {
133 left = QMIN( redClick, redDrag );
134 right = QMAX( redClick, redDrag );
135 }
136 else if(displayedChannel == GREEN)
137 {
138 left = QMIN( greenClick, greenDrag );
139 right = QMAX( greenClick, greenDrag );
140 }
141 else if(displayedChannel == BLUE)
142 {
143 left = QMIN( blueClick, blueDrag );
144 right = QMAX( blueClick, blueDrag );
145 }
146 else
147 { left = 0; right = 0; }
148}

References BLUE, blueClick, blueDrag, displayedChannel, GREEN, greenClick, greenDrag, lumClick, lumDrag, LUMINOSITY, RED, redClick, and redDrag.

Referenced by mouseMoveEvent(), mousePressEvent(), nearBoundary(), paintEvent(), and selectAll().

◆ indexToDisplay()

int HistogramInterface::indexToDisplay ( int val)
private

converts index in 0-255 ranges to screen coordinate

Definition at line 155 of file histogramInterface.cpp.

156{
157 return (index* (width()-1) ) / 255;
158}

References width.

Referenced by paintEvent().

◆ minimumSizeHint()

QSize HistogramInterface::minimumSizeHint ( ) const
virtual

Definition at line 291 of file histogramInterface.cpp.

292{
293 return QSize( 256,100 + COLOR_BAR_MARGIN + 2*COLOR_BAR_BORDER + COLOR_BAR_HEIGHT );
294}
#define COLOR_BAR_MARGIN
#define COLOR_BAR_BORDER
#define COLOR_BAR_HEIGHT

References COLOR_BAR_BORDER, COLOR_BAR_HEIGHT, and COLOR_BAR_MARGIN.

◆ mouseMoveEvent()

void HistogramInterface::mouseMoveEvent ( QMouseEvent * e)
protected

Definition at line 373 of file histogramInterface.cpp.

374{
375 //if not dragging a selection then update mouse cursor as appropriate
376 if(dragMode == NO_EFFECT)
377 {
378 if( nearBoundary(e->pos()) && currentMouseShape == NO_EFFECT )
379 {
381 setCursor( getCursor(MOVE_HOR_CURSOR) );
382 }
383 else if( !nearBoundary(e->pos()) && currentMouseShape == DRAG )
384 {
386 setCursor( getCursor(CROSS_CURSOR) );
387 }
388
389 return;
390 }
391
392 //compute index in 0-255 range from mouse coordinates
393 int x = QMAX( QMIN( e->pos().x(), width()-1 ), 0 );
394 int index = (int) displayToIndex( x );
395
396 //reset boundary
397 if(displayedChannel == LUMINOSITY) { lumDrag = index; }
398 else if(displayedChannel == RED) { redDrag = index; }
399 else if(displayedChannel == GREEN) { greenDrag = index; }
400 else if(displayedChannel == BLUE) { blueDrag = index; }
401
402 //repaint
403 repaint(false);
404
405 //emit selectection changed signal
406 int left, right;
407 getSelectedRange( left, right );
408 emit selectedRangeChanged();
409}
void selectedRangeChanged()
bool nearBoundary(QPoint p)
determines if mouse is near boundary
double displayToIndex(int val)
convert screen coordinate to index in 0-255 range
void getSelectedRange(int &left, int &right)
this utility function finds currently selected range
@ MOVE_HOR_CURSOR
Definition cursors.h:20

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.

◆ mousePressEvent()

void HistogramInterface::mousePressEvent ( QMouseEvent * e)
protected

Definition at line 312 of file histogramInterface.cpp.

313{
314 //begin drag mode!
315 dragMode = DRAG;
316
317 //compute index from mouse position
318 int index = (int) displayToIndex( e->pos().x() );
319
320 //get left and right to check for clicks near current boundaries
321 int left, right;
322 getSelectedRange( left, right );
323
324 //get click and drag handles
325 int *click, *drag;
327 {
328 click = &lumClick; drag = &lumDrag;
329 }
330 else if(displayedChannel == RED)
331 {
332 click = &redClick; drag = &redDrag;
333 }
334 else if(displayedChannel == GREEN)
335 {
336 click = &greenClick; drag = &greenDrag;
337 }
338 else
339 {
340 click = &blueClick; drag = &blueDrag;
341 }
342
343 //if within threshold of left then start dragging that side
344 if( index < left + DRAG_THRESHOLD &&
345 index > left - DRAG_THRESHOLD )
346 {
347 *click = right;
348 *drag = left;
349 return;
350 }
351 //if within threshold of left then start dragging that side
352 if( index < right + DRAG_THRESHOLD &&
353 index > right - DRAG_THRESHOLD )
354 {
355 *click = left;
356 *drag = right;
357 return;
358 }
359 //else begin new drag
360 else
361 {
362 *click = index;
363 *drag = index;
364 repaint(false);
365
366 //emit selectection changed signal
367 int left, right;
368 getSelectedRange( left, right );
369 emit selectedRangeChanged();
370 }
371}
#define DRAG_THRESHOLD

References blueClick, blueDrag, displayedChannel, displayToIndex(), DRAG, DRAG_THRESHOLD, dragMode, getSelectedRange(), GREEN, greenClick, greenDrag, lumClick, lumDrag, LUMINOSITY, RED, redClick, redDrag, and selectedRangeChanged().

◆ mouseReleaseEvent()

void HistogramInterface::mouseReleaseEvent ( QMouseEvent * e)
protected

Definition at line 411 of file histogramInterface.cpp.

412{
413 //set mouse drags to no longer have any effect on boundary
415
416 //update mouse cursor if necessary
417 if( !nearBoundary(e->pos()) && currentMouseShape == DRAG )
418 {
420 setCursor( getCursor(CROSS_CURSOR) );
421 }
422}

References CROSS_CURSOR, currentMouseShape, DRAG, dragMode, getCursor(), nearBoundary(), and NO_EFFECT.

◆ nearBoundary()

bool HistogramInterface::nearBoundary ( QPoint p)
private

determines if mouse is near boundary

Definition at line 296 of file histogramInterface.cpp.

297{
298 //compute index from mouse position
299 int index = (int) displayToIndex( p.x() );
300
301 //get left and right to check for clicks near current boundaries
302 int left, right;
303 getSelectedRange( left, right );
304
305 //check if within threshold of left or right boundaries
306 return ( (index < left + 1 + DRAG_THRESHOLD &&
307 index > left - DRAG_THRESHOLD) ||
308 (index < right + DRAG_THRESHOLD &&
309 index > right - 1 - DRAG_THRESHOLD) );
310}

References displayToIndex(), DRAG_THRESHOLD, and getSelectedRange().

Referenced by mouseMoveEvent(), and mouseReleaseEvent().

◆ paintEvent()

void HistogramInterface::paintEvent ( QPaintEvent * e)
protected

Definition at line 160 of file histogramInterface.cpp.

161{
162 //create buffer to draw in
163 QPixmap buffer( size() );
164 buffer.fill( Qt::white );
165
166 //create a painter pointing to the buffer
167 QPainter bufferPainter( &buffer );
168
169 //turn off clipping to make painting operations faster
170 bufferPainter.setClipping(false);
171
172 //initialize buffer with background brush
173 bufferPainter.fillRect( buffer.rect(), backgroundBrush() );
174
175 //get handle on histogram data, get max count, set default draw color, and find
176 //left and right boundaries of current selection
177 QColor color = Qt::black;
178 int* data = grayVals;
179 int maxCount = maxGRAYcount;
180
181 if(displayedChannel == RED) { data = redVals; color = Qt::red; maxCount = maxRcount; }
182 else if(displayedChannel == GREEN) { data = greenVals; color = Qt::green; maxCount = maxGcount; }
183 else if(displayedChannel == BLUE) { data = blueVals; color = Qt::blue; maxCount = maxBcount; }
184
185 int indexLeft, indexRight;
186 getSelectedRange(indexLeft,indexRight);
187 int displayLeft = indexToDisplay ( indexLeft );
188 int displayRight = indexToDisplay ( indexRight );
189
190 int histogramHeight = HISTOGRAM_HEIGHT;
191
192 //iterate over each pixel column
193 int x;
194 for(x=0; x<width(); x++)
195 {
196 double index = displayToIndex( x );
197 int indexL = (int)index;
198 double scaleR = index - indexL;
199
200 int h = 0;
201 if(indexL < 255)
202 {
203 h = (int) ((1-scaleR)*data[indexL] + scaleR*data[indexL+1]);
204 }
205 else
206 {
207 h = data[255];
208 }
209
210 //scale count so that the maxCount maps to the maximum height
211 double scaledH = (histogramHeight*h)/maxCount;
212 h = (int) scaledH;
213 //round up values between 0 and 1 so show data is there
214 if( h == 0 && scaledH > h) h++;
215
216 if(h > 0)
217 {
218 //use a gray color outside selected range
219 QColor usedColor = color;
220 if(x < displayLeft || x > displayRight) { usedColor = Qt::gray; }
221
222 bufferPainter.fillRect( QRect(x, histogramHeight - h,
223 1, h),
224 QBrush(usedColor) );
225 }
226
227 //if this is left or right boundary of selection and entire range not selected then
228 //draw a vertical black line to make it stand out more
229 if( (x == displayLeft || x == displayLeft+1 ||
230 x == displayRight || x == displayRight-1) )
231 {
232 bufferPainter.drawLine( x, 0, x, histogramHeight-1 );
233 }
234 }
235 //----
236 //paint color bar key below
237
238 //first a black border
239 bufferPainter.fillRect( QRect(0, histogramHeight + COLOR_BAR_MARGIN,
241 QBrush(Qt::black) );
242
243 //next the color gradient
244 QColor scaledColor;
245 for(x=COLOR_BAR_BORDER; x < width()-COLOR_BAR_BORDER; x++)
246 {
247 int index;
248 if(x <= displayLeft )
249 index = 0;
250 else if(x >= displayRight)
251 index = 255;
252 else
253 index = (int) (255.0*(x-displayLeft))/(displayRight - displayLeft);
254
255 int r = color.red();
256 int g = color.green();
257 int b = color.blue();
258
259 if( r != 0) r = index;
260 if( g != 0) g = index;
261 if( b != 0) b = index;
262
263 //black color was used when adjusting luminance, scale to white instead (since black is 0)
264 if( color == Qt::black )
265 { r = g = b = index; }
266
267 scaledColor.setRgb( r,g,b );
268 bufferPainter.fillRect( QRect(x, histogramHeight + COLOR_BAR_MARGIN + COLOR_BAR_BORDER,
270 QBrush(scaledColor) );
271 }
272
273 //end painter
274 bufferPainter.end();
275
276 //blit buffer to screen
277 bitBlt( this,
278 e->rect().x(), e->rect().y(),
279 &buffer,
280 e->rect().x(), e->rect().y(),
281 e->rect().width(), e->rect().height() );
282}
float * buffer
Definition blur.cpp:80
int indexToDisplay(int val)
converts index in 0-255 ranges to screen coordinate
#define HISTOGRAM_HEIGHT
long b

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.

◆ resetBoundaries()

void HistogramInterface::resetBoundaries ( )

resets all boundaries

Definition at line 457 of file histogramInterface.cpp.

458{
460 lumDrag = redDrag = greenDrag = blueDrag = 255;
461 repaint(false);
462 emit selectedRangeChanged();
463}

References blueClick, blueDrag, greenClick, greenDrag, lumClick, lumDrag, redClick, redDrag, and selectedRangeChanged().

Referenced by HistogramInterface(), and HistogramEditor::resetAction().

◆ resizeEvent()

void HistogramInterface::resizeEvent ( QResizeEvent * )
protected

Definition at line 119 of file histogramInterface.cpp.

120{
121 repaint(false);
122}

◆ selectAll

void HistogramInterface::selectAll ( )
privateslot

Definition at line 424 of file histogramInterface.cpp.

425{
426 //reset boundary
427 if(displayedChannel == LUMINOSITY) { lumClick = 0, lumDrag = 255; }
428 else if(displayedChannel == RED) { redClick = 0; redDrag = 255; }
429 else if(displayedChannel == GREEN) { greenClick = 0; greenDrag = 255; }
430 else if(displayedChannel == BLUE) { blueClick = 0; blueDrag = 255; }
431 repaint(false);
432
433 //emit selectection changed signal
434 int left, right;
435 getSelectedRange( left, right );
436 emit selectedRangeChanged();
437}

References BLUE, blueClick, blueDrag, displayedChannel, getSelectedRange(), GREEN, greenClick, greenDrag, lumClick, lumDrag, LUMINOSITY, RED, redClick, redDrag, and selectedRangeChanged().

Referenced by HistogramInterface().

◆ selectedRangeChanged

void HistogramInterface::selectedRangeChanged ( )
signal

◆ setDisplayChannel()

void HistogramInterface::setDisplayChannel ( DISPLAYED_CHANNEL channel)

Sets currently displayed channel.

Definition at line 284 of file histogramInterface.cpp.

285{
286 //set mode and repaint
287 displayedChannel = channel;
288 repaint(false);
289}

References displayedChannel.

Referenced by HistogramEditor::selectHistogramType().

Member Data Documentation

◆ blueClick

int HistogramInterface::blueClick
private

◆ blueDrag

int HistogramInterface::blueDrag
private

◆ blueVals

int HistogramInterface::blueVals[256]
private

Definition at line 104 of file histogramInterface.h.

Referenced by HistogramInterface(), and paintEvent().

◆ currentMouseShape

DRAG_MODE HistogramInterface::currentMouseShape
private

current mouse shape.

by caching this value we avoid resetting the mouse cursor every time it moves etc.

Definition at line 124 of file histogramInterface.h.

Referenced by HistogramInterface(), mouseMoveEvent(), and mouseReleaseEvent().

◆ displayedChannel

DISPLAYED_CHANNEL HistogramInterface::displayedChannel
private

Currently displayed channel.

Definition at line 99 of file histogramInterface.h.

Referenced by getSelectedRange(), HistogramInterface(), mouseMoveEvent(), mousePressEvent(), paintEvent(), selectAll(), and setDisplayChannel().

◆ dragMode

DRAG_MODE HistogramInterface::dragMode
private

effect of mouse drags

Definition at line 120 of file histogramInterface.h.

Referenced by HistogramInterface(), mouseMoveEvent(), mousePressEvent(), and mouseReleaseEvent().

◆ grayVals

int HistogramInterface::grayVals[256]
private

Definition at line 105 of file histogramInterface.h.

Referenced by HistogramInterface(), and paintEvent().

◆ greenClick

int HistogramInterface::greenClick
private

◆ greenDrag

int HistogramInterface::greenDrag
private

◆ greenVals

int HistogramInterface::greenVals[256]
private

Definition at line 103 of file histogramInterface.h.

Referenced by HistogramInterface(), and paintEvent().

◆ lumClick

int HistogramInterface::lumClick
private

left and right bounds for each channel

Definition at line 111 of file histogramInterface.h.

Referenced by getHistBoundaries(), getSelectedRange(), mousePressEvent(), resetBoundaries(), and selectAll().

◆ lumDrag

int HistogramInterface::lumDrag
private

◆ maxBcount

int HistogramInterface::maxBcount
private

Definition at line 108 of file histogramInterface.h.

Referenced by HistogramInterface(), and paintEvent().

◆ maxGcount

int HistogramInterface::maxGcount
private

Definition at line 108 of file histogramInterface.h.

Referenced by HistogramInterface(), and paintEvent().

◆ maxGRAYcount

int HistogramInterface::maxGRAYcount
private

Definition at line 108 of file histogramInterface.h.

Referenced by HistogramInterface(), and paintEvent().

◆ maxRcount

int HistogramInterface::maxRcount
private

max r,g,b, and gray counts

Definition at line 108 of file histogramInterface.h.

Referenced by HistogramInterface(), and paintEvent().

◆ origImageSize

QSize HistogramInterface::origImageSize
private

original image dimensions, needed for painting

Definition at line 117 of file histogramInterface.h.

Referenced by HistogramInterface().

◆ redClick

int HistogramInterface::redClick
private

◆ redDrag

int HistogramInterface::redDrag
private

◆ redVals

int HistogramInterface::redVals[256]
private

color and luminosity histograms

Definition at line 102 of file histogramInterface.h.

Referenced by HistogramInterface(), and paintEvent().


The documentation for this class was generated from the following files: