AlbumShaper  1.0a3
selectionPlacementInterface.cpp
Go to the documentation of this file.
1 //==============================================
2 // copyright : (C) 2003-2005 by Will Stokes
3 //==============================================
4 // This program is free software; you can redistribute it
5 // and/or modify it under the terms of the GNU General
6 // Public License as published by the Free Software
7 // Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //==============================================
10 
11 //Systemwide includes
12 #include <qapplication.h>
13 #include <qpainter.h>
14 #include <qcursor.h>
15 //Added by qt3to4:
16 #include <QPixmap>
17 #include <QMouseEvent>
18 #include <QPaintEvent>
19 
20 #define MIN(x,y) ((x) < (y) ? (x) : (y))
21 #define MAX(x,y) ((x) > (y) ? (x) : (y))
22 
23 //Projectwide includes
25 #include "../../backend/tools/imageTools.h"
26 #include "../cursors.h"
27 
28 //==============================================
30  QWidget *parent, const char* name )
31  : QWidget (parent, name )
32 {
33  //store original image dimensions
34  getImageSize( imageFilename, origImageSize );
35 
36  //construct scaled image
37  scaleImage( imageFilename, scaledImage, 200, 200 );
38 
39  //construct an unselected scaled image
41  int x, y;
42  QRgb* rgb;
43  uchar* scanLine;
44  for( y=0; y<unselectedScaledImage.height(); y++)
45  {
46  //iterate over each selected pixel in scanline
47  scanLine = unselectedScaledImage.scanLine(y);
48  for( x=0; x<unselectedScaledImage.width(); x++)
49  {
50  //compress dynamic range to 25% of original
51  rgb = ((QRgb*)scanLine+x);
52 
53  double r = ((double)qRed(*rgb) )/255.0;
54  double g = ((double)qGreen(*rgb) )/255.0;
55  double b = ((double)qBlue(*rgb) )/255.0;
56 
57  //convert to hsv
58  double h,s,v;
59  RGBtoHSV(r,g,b,&h,&s,&v);
60 
61  //scale and clamp v
62  v*=0.25;
63 
64  //convert adjusted color back to rgb colorspace and clamp
65  HSVtoRGB( &r,&g,&b, h,s,v);
66  int rp = (int) MIN( MAX((r*255), 0), 255 );
67  int gp = (int) MIN( MAX((g*255), 0), 255 );
68  int bp = (int) MIN( MAX((b*255), 0), 255 );
69 
70  //set adjusted color value
71  *rgb = qRgb(rp,gp,bp);
72  }
73  }
74 
75  //watch mouse movements in order to drag selection
76  //watch mouse movements in order to move split point between adjusted and original image
77  setMouseTracking(true);
78 
79  //by default no in dragging mode
80  currentlyDragging = false;
82 
83  //accept focus when clicked on
84  setFocusPolicy( Qt::ClickFocus );
85 
86  //init selection area
87  selection.setTopLeft( QPoint( -1, -1 ) );
88  selection.setBottomRight( QPoint( -1, -1 ) );
89 }
90 //==============================================
92 //==============================================
94 {
95  //if no scaled image just return
96  if(scaledImage.isNull()) { return; }
97 
98  //create buffer to draw in
99  QPixmap buffer( size() );
100 
101  //create a painter pointing to the buffer
102  QPainter bufferPainter( &buffer );
103 
104  //turn off clipping to make painting operations faster
105  bufferPainter.setClipping(false);
106 
107  //initialize buffer with background brush
108  bufferPainter.fillRect( buffer.rect(), backgroundBrush() );
109 
110  int xOffset = (width() - scaledImage.width()) / 2;
111  int yOffset = (height() - scaledImage.height()) / 2;
112 
113  //selection not set yet, simply paint the scaled image normally
114  if(selection.width() == 0 || selection.height() == 0 )
115  {
116  bufferPainter.drawImage( QPoint(xOffset, yOffset), scaledImage );
117  }
118  //selection present...
119  else
120  {
121  //first paint using unselected coloring
122  bufferPainter.drawImage( QPoint(xOffset, yOffset), unselectedScaledImage );
123 
124  //convert selection coordinates to display space
125  QRect displayRect = imageToDisplay( selection );
126  QPoint topLeft = displayRect.topLeft() + QPoint( xOffset, yOffset );
127  QPoint bottomRight = displayRect.bottomRight() + QPoint( xOffset, yOffset );
128 
129  //now paint selected region in color
130  bufferPainter.drawImage( topLeft.x(), topLeft.y(),
131  scaledImage,
132  displayRect.left(), displayRect.top(),
133  displayRect.width(), displayRect.height() );
134 
135 
136  //paint thin line around selected region to help it stand out even more
137  if( selection.width() < origImageSize.width() ||
138  selection.height() < origImageSize.height() )
139  {
140  QPen pen;
141  pen.setColor( Qt::gray );
142  pen.setStyle( Qt::SolidLine );
143  pen.setWidth( 2 );
144  bufferPainter.setPen( pen);
145 
146  QRect selctRect( topLeft, bottomRight );
147  bufferPainter.drawRect(selctRect);
148  }
149  }
150 
151  //end painter
152  bufferPainter.end();
153 
154  //blit buffer to screen
155  bitBlt( this,
156  e->rect().x(), e->rect().y(),
157  &buffer,
158  e->rect().x(), e->rect().y(),
159  e->rect().width(), e->rect().height() );
160 }
161 //==============================================
163 { return minimumSizeHint(); }
164 //==============================================
166 { return scaledImage.size(); }
167 //==============================================
169 {
170  if( selection.width() == 0 || selection.height() == 0 )
171  { return false; }
172 
173  QRect displayRect = imageToDisplay( selection );
174 
175  //if the entire image is visible then no rectangle can be dragged so just
176  //return false so a drag cursor never becomes visible since it might
177  //confuse the user into thinking s/he could actually drag it
178  if( displayRect.width() == scaledImage.width() &&
179  displayRect.height() == scaledImage.height() )
180  return false;
181 
182  //determine if mouse cursor is over region
183  int xOffset = (width() - scaledImage.width() ) / 2;
184  int yOffset = (height() - scaledImage.height()) / 2;
185 
186  return ( p.x() >= xOffset + displayRect.left() &&
187  p.x() <= xOffset + displayRect.right() &&
188  p.y() >= yOffset + displayRect.top() &&
189  p.y() <= yOffset + displayRect.bottom() );
190 }
191 //==============================================
193 {
194  //compute new viewing center
195  QPoint center = QPoint( ((origImageSize.width()-1) * mousePosition.x()) / (width()-1),
196  ((origImageSize.height()-1) * mousePosition.y()) / (height()-1) );
197  //move selection
198  int sW = selection.width();
199  int sH = selection.height();
200  selection.setLeft( center.x() - sW/2 );
201  selection.setTop( center.y() - sH/2 );
202  selection.setRight( selection.left() + sW -1 );
203  selection.setBottom( selection.top() + sH -1 );
204 
205  //ensure selection window never goes out of bounds
206  if(selection.left() < 0 )
207  selection.moveBy( -selection.left(), 0 );
208 
209  if(selection.right() > origImageSize.width() - 1 )
210  selection.moveBy( (origImageSize.width() - 1) - selection.right(), 0 );
211 
212  if(selection.top() < 0 )
213  selection.moveBy( 0, -selection.top() );
214 
215  if(selection.bottom() > origImageSize.height() - 1 )
216  selection.moveBy( 0, (origImageSize.height() - 1) - selection.bottom() );
217 
218  //repaint and emit placement changed signal
219  repaint(false);
220  emit placementChanged( selection );
221 }
222 //==============================================
224 {
225  //if mouse press is not over the region then center viewed area over mouse press
227  {
228  recenterSelection(e->pos());
230  setCursor( getCursor(MOVE_SELECTION_CURSOR) );
231  }
232 
233  //enter dragging mode
234  currentlyDragging = true;
235 }
236 //==============================================
238 {
239  //if not dragging update mosue cursor
240  if(!currentlyDragging)
241  {
242  if( !overRegion(e->pos() ) && currentMouseShapeIsDrag )
243  {
244  currentMouseShapeIsDrag = false;
245  setCursor( Qt::ArrowCursor );
246  }
247  else if( overRegion(e->pos() ) && !currentMouseShapeIsDrag )
248  {
250  setCursor( getCursor(MOVE_SELECTION_CURSOR) );
251 
252  }
253  }
254  //move selection
255  else { recenterSelection(e->pos()); }
256 }
257 //==============================================
259 {
260  //disable dragging
261  currentlyDragging = false;
262 }
263 //==============================================
265 {
266  //set top left
267  QRect res;
268  res.setTopLeft(QPoint( (int) (0.5+ (1.0*scaledImage.width()*r.left()) / origImageSize.width()),
269  (int) (0.5+ (1.0*scaledImage.height()*r.top()) / origImageSize.height()) ));
270 
271  //set width/height
272  res.setWidth( (scaledImage.width() *r.width()) / origImageSize.width() );
273  res.setHeight( (scaledImage.height() *r.height()) / origImageSize.height() );
274 
275  //if against the right hand size make sure scaled display coordiantes are also
276  //against edge. rounding prevents this from occuring and is noticeable since selection
277  //rectangle appears to never be at every edge.
278  if( r.right() == origImageSize.width() - 1)
279  { res.moveBy( (scaledImage.width()-1) - res.right(), 0 ); }
280 
281  if( r.bottom() == origImageSize.height() - 1)
282  { res.moveBy( 0, (scaledImage.height()-1) - res.bottom() ); }
283 
284  //return new rect
285  return res;
286 }
287 //==============================================
289 {
290  return selection;
291 }
292 //==============================================
294 {
295  this->selection = selection;
296  repaint(false);
297 }
298 //==============================================
QPoint bottomRight
bool currentlyDragging
dragging the mouse only moves the selection if the mouse button is pressed first over the selected re...
QRect getSelectedRegion()
Returns the selected region in image space.
QPoint topLeft
void HSVtoRGB(double *r, double *g, double *b, double h, double s, double v)
Convert a HSV color triplet to RGB.
Definition: imageTools.cpp:264
#define MAX(x, y)
void recenterSelection(QPoint mousePosition)
util function used to center selection about mouse location
QRect imageToDisplay(QRect r)
convert rectangle from image coordinates to display coordinates
QSize origImageSize
original image dimensions
long b
Definition: jpegInternal.h:125
QImage unselectedScaledImage
Unselected scaled image (desaturated version of scaled image)
int width
Definition: blur.cpp:79
void setSelectedRegion(QRect selection)
Set the select region using image space coordinates.
bool scaleImage(QString fileIn, QString fileOut, int newWidth, int newHeight)
Scale image and save copy to disk.
Definition: imageTools.cpp:157
bool getImageSize(const char *filename, QSize &size)
Get image dimensions.
Definition: imageTools.cpp:192
bool currentMouseShapeIsDrag
current mouse shape.
const QCursor & getCursor(CUSTOM_CURSOR_TYPE type)
Definition: cursors.cpp:52
QImage scaledImage
Scaled image used for display purposes.
#define MIN(x, y)
bool overRegion(QPoint p)
util function used to determine if mouse is over selected region
float * buffer
Definition: blur.cpp:80
SelectionPlacementInterface(QString imageFilename, QWidget *parent=0, const char *name=0)
Creates layout.
void RGBtoHSV(double r, double g, double b, double *h, double *s, double *v)
Convert a RGB color triplet to HSV.
Definition: imageTools.cpp:231
int height
Definition: blur.cpp:79