18 #ifndef QGSIMAGEOPERATION_H
19 #define QGSIMAGEOPERATION_H
25 #include "qgis_core.h"
75 static void convertToGrayscale( QImage &image, GrayscaleMode mode = GrayscaleLuminosity );
87 static void adjustBrightnessContrast( QImage &image,
int brightness,
double contrast );
97 static void adjustHueSaturation( QImage &image,
double saturation,
const QColor &colorizeColor = QColor(),
98 double colorizeStrength = 1.0 );
105 static void multiplyOpacity( QImage &image,
double factor );
113 static void overlayColor( QImage &image,
const QColor &color );
124 bool shadeExterior =
true;
130 bool useMaxDistance =
true;
136 double spread = 10.0;
162 static void stackBlur( QImage &image,
int radius,
bool alphaOnly =
false );
172 static QImage *gaussianBlur( QImage &image,
int radius )
SIP_FACTORY;
179 static void flipImage( QImage &image,
FlipType type );
191 static QRect nonTransparentImageRect(
const QImage &image, QSize minSize = QSize(),
bool center =
false );
202 static QImage cropTransparent(
const QImage &image, QSize minSize = QSize(),
bool center =
false );
207 enum LineOperationDirection
212 template <
class BlockOperation>
static void runBlockOperationInThreads( QImage &image, BlockOperation &operation, LineOperationDirection direction );
215 unsigned int beginLine;
216 unsigned int endLine;
217 unsigned int lineLength;
218 QImage *image =
nullptr;
222 template <
typename RectOperation>
static void runRectOperation( QImage &image, RectOperation &operation );
223 template <
class RectOperation>
static void runRectOperationOnWholeImage( QImage &image, RectOperation &operation );
226 template <
class PixelOperation>
static void runPixelOperation( QImage &image, PixelOperation &operation );
227 template <
class PixelOperation>
static void runPixelOperationOnWholeImage( QImage &image, PixelOperation &operation );
228 template <
class PixelOperation>
229 struct ProcessBlockUsingPixelOperation
231 explicit ProcessBlockUsingPixelOperation( PixelOperation &operation )
232 : mOperation( operation ) { }
234 typedef void result_type;
236 void operator()( ImageBlock &block )
238 for (
unsigned int y = block.beginLine; y < block.endLine; ++y )
240 QRgb *ref =
reinterpret_cast< QRgb *
>( block.image->scanLine( y ) );
241 for (
unsigned int x = 0; x < block.lineLength; ++x )
243 mOperation( ref[x], x, y );
248 PixelOperation &mOperation;
252 template <
typename LineOperation>
static void runLineOperation( QImage &image, LineOperation &operation );
253 template <
class LineOperation>
static void runLineOperationOnWholeImage( QImage &image, LineOperation &operation );
254 template <
class LineOperation>
255 struct ProcessBlockUsingLineOperation
257 explicit ProcessBlockUsingLineOperation( LineOperation &operation )
258 : mOperation( operation ) { }
260 typedef void result_type;
262 void operator()( ImageBlock &block )
265 int bpl = block.image->bytesPerLine();
266 if ( mOperation.direction() == ByRow )
268 for (
unsigned int y = block.beginLine; y < block.endLine; ++y )
270 QRgb *ref =
reinterpret_cast< QRgb *
>( block.image->scanLine( y ) );
271 mOperation( ref, block.lineLength, bpl );
277 unsigned char *ref = block.image->scanLine( 0 ) + 4 * block.beginLine;
278 for (
unsigned int x = block.beginLine; x < block.endLine; ++x, ref += 4 )
280 mOperation(
reinterpret_cast< QRgb *
>( ref ), block.lineLength, bpl );
285 LineOperation &mOperation;
291 class GrayscalePixelOperation
294 explicit GrayscalePixelOperation(
const GrayscaleMode mode )
298 void operator()( QRgb &rgb,
int x,
int y );
303 static void grayscaleLightnessOp( QRgb &rgb );
304 static void grayscaleLuminosityOp( QRgb &rgb );
305 static void grayscaleAverageOp( QRgb &rgb );
308 class BrightnessContrastPixelOperation
311 BrightnessContrastPixelOperation(
const int brightness,
const double contrast )
312 : mBrightness( brightness )
313 , mContrast( contrast )
316 void operator()( QRgb &rgb,
int x,
int y );
324 class HueSaturationPixelOperation
327 HueSaturationPixelOperation(
const double saturation,
const bool colorize,
328 const int colorizeHue,
const int colorizeSaturation,
329 const double colorizeStrength )
330 : mSaturation( saturation )
331 , mColorize( colorize )
332 , mColorizeHue( colorizeHue )
333 , mColorizeSaturation( colorizeSaturation )
334 , mColorizeStrength( colorizeStrength )
337 void operator()( QRgb &rgb,
int x,
int y );
343 int mColorizeSaturation;
344 double mColorizeStrength;
346 static int adjustColorComponent(
int colorComponent,
int brightness,
double contrastFactor );
349 class MultiplyOpacityPixelOperation
352 explicit MultiplyOpacityPixelOperation(
const double factor )
356 void operator()( QRgb &rgb,
int x,
int y );
362 class ConvertToArrayPixelOperation
365 ConvertToArrayPixelOperation(
const int width,
double *array,
const bool exterior =
true )
368 , mExterior( exterior )
372 void operator()( QRgb &rgb,
int x,
int y );
376 double *mArray =
nullptr;
380 class ShadeFromArrayOperation
383 ShadeFromArrayOperation(
const int width,
double *array,
const double spread,
384 const DistanceTransformProperties &properties )
388 , mProperties( properties )
390 mSpreadSquared = std::pow( mSpread, 2.0 );
393 void operator()( QRgb &rgb,
int x,
int y );
397 double *mArray =
nullptr;
399 double mSpreadSquared;
400 const DistanceTransformProperties &mProperties;
402 static void distanceTransform2d(
double *im,
int width,
int height );
403 static void distanceTransform1d(
double *f,
int n,
int *v,
double *z,
double *d );
404 static double maxValueInDistanceTransformArray(
const double *array,
unsigned int size );
407 class StackBlurLineOperation
410 StackBlurLineOperation(
int alpha, LineOperationDirection direction,
bool forwardDirection,
int i1,
int i2 )
412 , mDirection( direction )
413 , mForwardDirection( forwardDirection )
418 typedef void result_type;
420 LineOperationDirection direction() {
return mDirection; }
422 void operator()( QRgb *startRef,
int lineLength,
int bytesPerLine )
424 unsigned char *p =
reinterpret_cast< unsigned char *
>( startRef );
426 int increment = ( mDirection == QgsImageOperation::ByRow ) ? 4 : bytesPerLine;
427 if ( !mForwardDirection )
429 p += ( lineLength - 1 ) * increment;
430 increment = -increment;
433 for (
int i = mi1; i <= mi2; ++i )
439 for (
int j = 1; j < lineLength; ++j, p += increment )
441 for (
int i = mi1; i <= mi2; ++i )
443 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * mAlpha / 16 ) >> 4;
450 LineOperationDirection mDirection;
451 bool mForwardDirection;
456 static double *createGaussianKernel(
int radius );
458 class GaussianBlurOperation
461 GaussianBlurOperation(
int radius, LineOperationDirection direction, QImage *destImage,
double *kernel )
463 , mDirection( direction )
464 , mDestImage( destImage )
465 , mDestImageBpl( destImage->bytesPerLine() )
469 typedef void result_type;
471 void operator()( ImageBlock &block );
475 LineOperationDirection mDirection;
476 QImage *mDestImage =
nullptr;
478 double *mKernel =
nullptr;
480 inline QRgb gaussianBlurVertical(
int posy,
unsigned char *sourceFirstLine,
int sourceBpl,
int height );
481 inline QRgb gaussianBlurHorizontal(
int posx,
unsigned char *sourceFirstLine,
int width );
487 class FlipLineOperation
490 explicit FlipLineOperation( LineOperationDirection direction )
491 : mDirection( direction )
494 typedef void result_type;
496 LineOperationDirection direction() {
return mDirection; }
498 void operator()( QRgb *startRef,
int lineLength,
int bytesPerLine );
501 LineOperationDirection mDirection;
507 #endif // QGSIMAGEOPERATION_H