QGIS API Documentation  2.18.3-Las Palmas (77b8c3d)
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  {
53  GrayscaleOff
54  };
55 
58  enum FlipType
59  {
61  FlipVertical
62  };
63 
68  static void convertToGrayscale( QImage &image, const GrayscaleMode mode = GrayscaleLuminosity );
69 
79  static void adjustBrightnessContrast( QImage &image, const int brightness, const double contrast );
80 
88  static void adjustHueSaturation( QImage &image, const double saturation, const QColor& colorizeColor = QColor(),
89  const double colorizeStrength = 1.0 );
90 
95  static void multiplyOpacity( QImage &image, const double factor );
96 
102  static void overlayColor( QImage &image, const QColor& color );
103 
106  {
108  : shadeExterior( true )
109  , useMaxDistance( true )
110  , spread( 10.0 )
111  , ramp( nullptr )
112  { }
113 
126  double spread;
130  };
131 
138  static void distanceTransform( QImage &image, const DistanceTransformProperties& properties );
139 
148  static void stackBlur( QImage &image, const int radius, const bool alphaOnly = false );
149 
157  static QImage* gaussianBlur( QImage &image, const int radius );
158 
163  static void flipImage( QImage &image, FlipType type );
164 
174  static QRect nonTransparentImageRect( const QImage & image, QSize minSize = QSize(), bool center = false );
175 
184  static QImage cropTransparent( const QImage & image, QSize minSize = QSize(), bool center = false );
185 
186  private:
187 
188  //for blocked operations
189  enum LineOperationDirection
190  {
191  ByRow,
192  ByColumn
193  };
194  template <class BlockOperation> static void runBlockOperationInThreads( QImage &image, BlockOperation& operation, LineOperationDirection direction );
195  struct ImageBlock
196  {
197  unsigned int beginLine;
198  unsigned int endLine;
199  unsigned int lineLength;
200  QImage* image;
201  };
202 
203  //for rect operations
204  template <typename RectOperation> static void runRectOperation( QImage &image, RectOperation& operation );
205  template <class RectOperation> static void runRectOperationOnWholeImage( QImage &image, RectOperation& operation );
206 
207  //for per pixel operations
208  template <class PixelOperation> static void runPixelOperation( QImage &image, PixelOperation& operation );
209  template <class PixelOperation> static void runPixelOperationOnWholeImage( QImage &image, PixelOperation& operation );
210  template <class PixelOperation>
211  struct ProcessBlockUsingPixelOperation
212  {
213  explicit ProcessBlockUsingPixelOperation( PixelOperation& operation )
214  : mOperation( operation ) { }
215 
216  typedef void result_type;
217 
218  void operator()( ImageBlock& block )
219  {
220  for ( unsigned int y = block.beginLine; y < block.endLine; ++y )
221  {
222  QRgb* ref = reinterpret_cast< QRgb* >( block.image->scanLine( y ) );
223  for ( unsigned int x = 0; x < block.lineLength; ++x )
224  {
225  mOperation( ref[x], x, y );
226  }
227  }
228  }
229 
230  PixelOperation& mOperation;
231  };
232 
233  //for linear operations
234  template <typename LineOperation> static void runLineOperation( QImage &image, LineOperation& operation );
235  template <class LineOperation> static void runLineOperationOnWholeImage( QImage &image, LineOperation& operation );
236  template <class LineOperation>
237  struct ProcessBlockUsingLineOperation
238  {
239  explicit ProcessBlockUsingLineOperation( LineOperation& operation )
240  : mOperation( operation ) { }
241 
242  typedef void result_type;
243 
244  void operator()( ImageBlock& block )
245  {
246  //do something with whole lines
247  int bpl = block.image->bytesPerLine();
248  if ( mOperation.direction() == ByRow )
249  {
250  for ( unsigned int y = block.beginLine; y < block.endLine; ++y )
251  {
252  QRgb* ref = reinterpret_cast< QRgb* >( block.image->scanLine( y ) );
253  mOperation( ref, block.lineLength, bpl );
254  }
255  }
256  else
257  {
258  //by column
259  unsigned char* ref = block.image->scanLine( 0 ) + 4 * block.beginLine;
260  for ( unsigned int x = block.beginLine; x < block.endLine; ++x, ref += 4 )
261  {
262  mOperation( reinterpret_cast< QRgb* >( ref ), block.lineLength, bpl );
263  }
264  }
265  }
266 
267  LineOperation& mOperation;
268  };
269 
270 
271  //individual operation implementations
272 
273  class GrayscalePixelOperation
274  {
275  public:
276  explicit GrayscalePixelOperation( const GrayscaleMode mode )
277  : mMode( mode )
278  { }
279 
280  void operator()( QRgb& rgb, const int x, const int y );
281 
282  private:
283  GrayscaleMode mMode;
284  };
285  static void grayscaleLightnessOp( QRgb& rgb );
286  static void grayscaleLuminosityOp( QRgb& rgb );
287  static void grayscaleAverageOp( QRgb& rgb );
288 
289 
290  class BrightnessContrastPixelOperation
291  {
292  public:
293  BrightnessContrastPixelOperation( const int brightness, const double contrast )
294  : mBrightness( brightness )
295  , mContrast( contrast )
296  { }
297 
298  void operator()( QRgb& rgb, const int x, const int y );
299 
300  private:
301  int mBrightness;
302  double mContrast;
303  };
304 
305 
306  class HueSaturationPixelOperation
307  {
308  public:
309  HueSaturationPixelOperation( const double saturation, const bool colorize,
310  const int colorizeHue, const int colorizeSaturation,
311  const double colorizeStrength )
312  : mSaturation( saturation )
313  , mColorize( colorize )
314  , mColorizeHue( colorizeHue )
315  , mColorizeSaturation( colorizeSaturation )
316  , mColorizeStrength( colorizeStrength )
317  { }
318 
319  void operator()( QRgb& rgb, const int x, const int y );
320 
321  private:
322  double mSaturation; // [0, 2], 1 = no change
323  bool mColorize;
324  int mColorizeHue;
325  int mColorizeSaturation;
326  double mColorizeStrength; // [0,1]
327  };
328  static int adjustColorComponent( int colorComponent, int brightness, double contrastFactor );
329 
330 
331  class MultiplyOpacityPixelOperation
332  {
333  public:
334  explicit MultiplyOpacityPixelOperation( const double factor )
335  : mFactor( factor )
336  { }
337 
338  void operator()( QRgb& rgb, const int x, const int y );
339 
340  private:
341  double mFactor;
342  };
343 
344  class ConvertToArrayPixelOperation
345  {
346  public:
347  ConvertToArrayPixelOperation( const int width, double * array, const bool exterior = true )
348  : mWidth( width )
349  , mArray( array )
350  , mExterior( exterior )
351  {
352  }
353 
354  void operator()( QRgb& rgb, const int x, const int y );
355 
356  private:
357  int mWidth;
358  double * mArray;
359  bool mExterior;
360  };
361 
362  class ShadeFromArrayOperation
363  {
364  public:
365  ShadeFromArrayOperation( const int width, double* array, const double spread,
366  const DistanceTransformProperties& properties )
367  : mWidth( width )
368  , mArray( array )
369  , mSpread( spread )
370  , mProperties( properties )
371  {
372  mSpreadSquared = qPow( mSpread, 2.0 );
373  }
374 
375  void operator()( QRgb& rgb, const int x, const int y );
376 
377  private:
378  int mWidth;
379  double * mArray;
380  double mSpread;
381  double mSpreadSquared;
382  const DistanceTransformProperties& mProperties;
383  };
384  static void distanceTransform2d( double *im, int width, int height );
385  static void distanceTransform1d( double *f, int n, int *v, double *z, double *d );
386  static double maxValueInDistanceTransformArray( const double *array, const unsigned int size );
387 
388 
389  class StackBlurLineOperation
390  {
391  public:
392  StackBlurLineOperation( int alpha, LineOperationDirection direction, bool forwardDirection, int i1, int i2 )
393  : mAlpha( alpha )
394  , mDirection( direction )
395  , mForwardDirection( forwardDirection )
396  , mi1( i1 )
397  , mi2( i2 )
398  { }
399 
400  typedef void result_type;
401 
402  LineOperationDirection direction() { return mDirection; }
403 
404  void operator()( QRgb* startRef, const int lineLength, const int bytesPerLine );
405 
406  private:
407  int mAlpha;
408  LineOperationDirection mDirection;
409  bool mForwardDirection;
410  int mi1;
411  int mi2;
412  };
413 
414  static double *createGaussianKernel( const int radius );
415 
416  class GaussianBlurOperation
417  {
418  public:
419  GaussianBlurOperation( int radius, LineOperationDirection direction, QImage* destImage, double* kernel )
420  : mRadius( radius )
421  , mDirection( direction )
422  , mDestImage( destImage )
423  , mDestImageBpl( destImage->bytesPerLine() )
424  , mKernel( kernel )
425  {}
426 
427  typedef void result_type;
428 
429  void operator()( ImageBlock& block );
430 
431  private:
432  int mRadius;
433  LineOperationDirection mDirection;
434  QImage* mDestImage;
435  int mDestImageBpl;
436  double* mKernel;
437 
438  inline QRgb gaussianBlurVertical( const int posy, unsigned char *sourceFirstLine, const int sourceBpl, const int height );
439  inline QRgb gaussianBlurHorizontal( const int posx, unsigned char *sourceFirstLine, const int width );
440  };
441 
442  //flip
443 
444 
445  class FlipLineOperation
446  {
447  public:
448  explicit FlipLineOperation( LineOperationDirection direction )
449  : mDirection( direction )
450  { }
451 
452  typedef void result_type;
453 
454  LineOperationDirection direction() { return mDirection; }
455 
456  void operator()( QRgb* startRef, const int lineLength, const int bytesPerLine );
457 
458  private:
459  LineOperationDirection mDirection;
460  };
461 
462 
463 };
464 
465 #endif // QGSIMAGEOPERATION_H
466 
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.
Abstract base class for color ramps.
Struct for storing properties of a distance transform operation.