QGIS API Documentation  2.8.6-Wien
qgsimageoperation.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsimageoperation.h
3  --------------------
4  begin : January 2015
5  copyright : (C) 2015 by Nyall Dawson
6  email : nyall.dawson@gmail.com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #ifndef QGSIMAGEOPERATION_H
19 #define QGSIMAGEOPERATION_H
20 
21 #include <QImage>
22 #include <QColor>
23 #include <QtCore/qmath.h>
24 
26 
41 class CORE_EXPORT QgsImageOperation
42 {
43 
44  public:
45 
49  {
50  GrayscaleLightness, /*< keep the lightness of the color, drops the saturation */
51  GrayscaleLuminosity, /*< grayscale by perceptual luminosity (weighted sum of color RGB components) */
52  GrayscaleAverage /*< grayscale by taking average of color RGB components */
53  };
54 
57  enum FlipType
58  {
59  FlipHorizontal, /*< flip the image horizontally */
60  FlipVertical /*< flip the image vertically */
61  };
62 
67  static void convertToGrayscale( QImage &image, const GrayscaleMode mode = GrayscaleLuminosity );
68 
78  static void adjustBrightnessContrast( QImage &image, const int brightness, const double contrast );
79 
87  static void adjustHueSaturation( QImage &image, const double saturation, const QColor& colorizeColor = QColor(),
88  const double colorizeStrength = 1.0 );
89 
94  static void multiplyOpacity( QImage &image, const double factor );
95 
101  static void overlayColor( QImage &image, const QColor& color );
102 
105  {
107  : shadeExterior( true )
108  , useMaxDistance( true )
109  , spread( 10.0 )
110  , ramp( NULL )
111  { }
112 
125  double spread;
129  };
130 
137  static void distanceTransform( QImage &image, const DistanceTransformProperties& properties );
138 
147  static void stackBlur( QImage &image, const int radius, const bool alphaOnly = false );
148 
156  static QImage* gaussianBlur( QImage &image, const int radius );
157 
162  static void flipImage( QImage &image, FlipType type );
163 
164  private:
165 
166  //for blocked operations
167  enum LineOperationDirection
168  {
169  ByRow,
170  ByColumn
171  };
172  template <class BlockOperation> static void runBlockOperationInThreads( QImage &image, BlockOperation& operation, LineOperationDirection direction );
173  struct ImageBlock
174  {
175  unsigned int beginLine;
176  unsigned int endLine;
177  unsigned int lineLength;
178  QImage* image;
179  };
180 
181  //for rect operations
182  template <typename RectOperation> static void runRectOperation( QImage &image, RectOperation& operation );
183  template <class RectOperation> static void runRectOperationOnWholeImage( QImage &image, RectOperation& operation );
184 
185  //for per pixel operations
186  template <class PixelOperation> static void runPixelOperation( QImage &image, PixelOperation& operation );
187  template <class PixelOperation> static void runPixelOperationOnWholeImage( QImage &image, PixelOperation& operation );
188  template <class PixelOperation>
189  struct ProcessBlockUsingPixelOperation
190  {
191  ProcessBlockUsingPixelOperation( PixelOperation& operation )
192  : mOperation( operation ) { }
193 
194  typedef void result_type;
195 
196  void operator()( ImageBlock& block )
197  {
198  for ( unsigned int y = block.beginLine; y < block.endLine; ++y )
199  {
200  QRgb* ref = ( QRgb* )block.image->scanLine( y );
201  for ( unsigned int x = 0; x < block.lineLength; ++x )
202  {
203  mOperation( ref[x], x, y );
204  }
205  }
206  }
207 
208  PixelOperation& mOperation;
209  };
210 
211  //for linear operations
212  template <typename LineOperation> static void runLineOperation( QImage &image, LineOperation& operation );
213  template <class LineOperation> static void runLineOperationOnWholeImage( QImage &image, LineOperation& operation );
214  template <class LineOperation>
215  struct ProcessBlockUsingLineOperation
216  {
217  ProcessBlockUsingLineOperation( LineOperation& operation )
218  : mOperation( operation ) { }
219 
220  typedef void result_type;
221 
222  void operator()( ImageBlock& block )
223  {
224  //do something with whole lines
225  int bpl = block.image->bytesPerLine();
226  if ( mOperation.direction() == ByRow )
227  {
228  for ( unsigned int y = block.beginLine; y < block.endLine; ++y )
229  {
230  QRgb* ref = ( QRgb* )block.image->scanLine( y );
231  mOperation( ref, block.lineLength, bpl );
232  }
233  }
234  else
235  {
236  //by column
237  unsigned char* ref = block.image->scanLine( 0 ) + 4 * block.beginLine;
238  for ( unsigned int x = block.beginLine; x < block.endLine; ++x, ref += 4 )
239  {
240  mOperation(( QRgb* )ref, block.lineLength, bpl );
241  }
242  }
243  }
244 
245  LineOperation& mOperation;
246  };
247 
248 
249  //individual operation implementations
250 
251  class GrayscalePixelOperation
252  {
253  public:
254  GrayscalePixelOperation( const GrayscaleMode mode )
255  : mMode( mode )
256  { }
257 
258  void operator()( QRgb& rgb, const int x, const int y );
259 
260  private:
261  GrayscaleMode mMode;
262  };
263  static void grayscaleLightnessOp( QRgb& rgb );
264  static void grayscaleLuminosityOp( QRgb& rgb );
265  static void grayscaleAverageOp( QRgb& rgb );
266 
267 
268  class BrightnessContrastPixelOperation
269  {
270  public:
271  BrightnessContrastPixelOperation( const int brightness, const double contrast )
272  : mBrightness( brightness )
273  , mContrast( contrast )
274  { }
275 
276  void operator()( QRgb& rgb, const int x, const int y );
277 
278  private:
279  int mBrightness;
280  double mContrast;
281  };
282 
283 
284  class HueSaturationPixelOperation
285  {
286  public:
287  HueSaturationPixelOperation( const double saturation, const bool colorize,
288  const int colorizeHue, const int colorizeSaturation,
289  const double colorizeStrength )
290  : mSaturation( saturation )
291  , mColorize( colorize )
292  , mColorizeHue( colorizeHue )
293  , mColorizeSaturation( colorizeSaturation )
294  , mColorizeStrength( colorizeStrength )
295  { }
296 
297  void operator()( QRgb& rgb, const int x, const int y );
298 
299  private:
300  double mSaturation; // [0, 2], 1 = no change
301  bool mColorize;
302  int mColorizeHue;
303  int mColorizeSaturation;
304  double mColorizeStrength; // [0,1]
305  };
306  static int adjustColorComponent( int colorComponent, int brightness, double contrastFactor );
307 
308 
309  class MultiplyOpacityPixelOperation
310  {
311  public:
312  MultiplyOpacityPixelOperation( const double factor )
313  : mFactor( factor )
314  { }
315 
316  void operator()( QRgb& rgb, const int x, const int y );
317 
318  private:
319  double mFactor;
320  };
321 
322  class ConvertToArrayPixelOperation
323  {
324  public:
325  ConvertToArrayPixelOperation( const int width, double * array, const bool exterior = true, const int alphaThreshold = 255 )
326  : mWidth( width )
327  , mArray( array )
328  , mExterior( exterior )
329  , mAlphaThreshold( alphaThreshold )
330  {
331  }
332 
333  void operator()( QRgb& rgb, const int x, const int y );
334 
335  private:
336  int mWidth;
337  double * mArray;
338  bool mExterior;
339  int mAlphaThreshold;
340  };
341 
342  class ShadeFromArrayOperation
343  {
344  public:
345  ShadeFromArrayOperation( const int width, double* array, const double spread,
346  const DistanceTransformProperties& properties )
347  : mWidth( width )
348  , mArray( array )
349  , mSpread( spread )
350  , mProperties( properties )
351  {
352  mSpreadSquared = qPow( mSpread, 2.0 );
353  }
354 
355  void operator()( QRgb& rgb, const int x, const int y );
356 
357  private:
358  int mWidth;
359  double * mArray;
360  double mSpread;
361  double mSpreadSquared;
362  const DistanceTransformProperties& mProperties;
363  };
364  static void distanceTransform2d( double *im, int width, int height );
365  static void distanceTransform1d( double *f, int n, int *v, double *z, double *d );
366  static double maxValueInDistanceTransformArray( const double *array, const unsigned int size );
367 
368 
369  class StackBlurLineOperation
370  {
371  public:
372  StackBlurLineOperation( int alpha, LineOperationDirection direction, bool forwardDirection, int i1, int i2 )
373  : mAlpha( alpha )
374  , mDirection( direction )
375  , mForwardDirection( forwardDirection )
376  , mi1( i1 )
377  , mi2( i2 )
378  { }
379 
380  typedef void result_type;
381 
382  LineOperationDirection direction() { return mDirection; }
383 
384  void operator()( QRgb* startRef, const int lineLength, const int bytesPerLine );
385 
386  private:
387  int mAlpha;
388  LineOperationDirection mDirection;
389  bool mForwardDirection;
390  int mi1;
391  int mi2;
392  };
393 
394  static double *createGaussianKernel( const int radius );
395 
396  class GaussianBlurOperation
397  {
398  public:
399  GaussianBlurOperation( int radius, LineOperationDirection direction, QImage* destImage, double* kernel )
400  : mRadius( radius )
401  , mDirection( direction )
402  , mDestImage( destImage )
403  , mDestImageBpl( destImage->bytesPerLine() )
404  , mKernel( kernel )
405  {}
406 
407  typedef void result_type;
408 
409  void operator()( ImageBlock& block );
410 
411  private:
412  int mRadius;
413  LineOperationDirection mDirection;
414  QImage* mDestImage;
415  int mDestImageBpl;
416  double* mKernel;
417 
418  inline QRgb gaussianBlurVertical( const int posy, unsigned char *sourceFirstLine, const int sourceBpl, const int height );
419  inline QRgb gaussianBlurHorizontal( const int posx, unsigned char *sourceFirstLine, const int width );
420  };
421 
422  //flip
423 
424 
425  class FlipLineOperation
426  {
427  public:
428  FlipLineOperation( LineOperationDirection direction )
429  : mDirection( direction )
430  { }
431 
432  typedef void result_type;
433 
434  LineOperationDirection direction() { return mDirection; }
435 
436  void operator()( QRgb* startRef, const int lineLength, const int bytesPerLine );
437 
438  private:
439  LineOperationDirection mDirection;
440  };
441 
442 
443 };
444 
445 #endif // QGSIMAGEOPERATION_H
446 
Contains operations and filters which apply to QImages.
double spread
Maximum distance (in pixels) for the distance transform shading to spread.
bool shadeExterior
Set to true to perform the distance transform on transparent pixels in the source image...
FlipType
Flip operation types.
bool useMaxDistance
Set to true to automatically calculate the maximum distance in the transform to use as the spread val...
QgsVectorColorRampV2 * ramp
Color ramp to use for shading the distance transform.
GrayscaleMode
Modes for converting a QImage to grayscale.
Struct for storing properties of a distance transform operation.