78 static void convertToGrayscale( QImage &image, GrayscaleMode mode = GrayscaleLuminosity,
QgsFeedback *feedback =
nullptr );
91 static void adjustBrightnessContrast( QImage &image,
int brightness,
double contrast,
QgsFeedback *feedback =
nullptr );
102 static void adjustHueSaturation( QImage &image,
double saturation,
const QColor &colorizeColor = QColor(),
103 double colorizeStrength = 1.0,
QgsFeedback *feedback =
nullptr );
111 static void multiplyOpacity( QImage &image,
double factor,
QgsFeedback *feedback =
nullptr );
119 static void overlayColor( QImage &image,
const QColor &color );
170 static void stackBlur( QImage &image,
int radius,
bool alphaOnly =
false,
QgsFeedback *feedback =
nullptr );
209 static QImage
cropTransparent( const QImage &image, QSize minSize = QSize(),
bool center = false );
214 enum LineOperationDirection
219 template <
class BlockOperation>
static void runBlockOperationInThreads( QImage &image, BlockOperation &operation, LineOperationDirection direction );
222 unsigned int beginLine;
223 unsigned int endLine;
224 unsigned int lineLength;
225 QImage *image =
nullptr;
229 template <
typename RectOperation>
static void runRectOperation( QImage &image, RectOperation &operation );
230 template <
class RectOperation>
static void runRectOperationOnWholeImage( QImage &image, RectOperation &operation );
233 template <
class PixelOperation>
static void runPixelOperation( QImage &image, PixelOperation &operation, QgsFeedback *feedback =
nullptr );
234 template <
class PixelOperation>
static void runPixelOperationOnWholeImage( QImage &image, PixelOperation &operation, QgsFeedback *feedback =
nullptr );
235 template <
class PixelOperation>
236 struct ProcessBlockUsingPixelOperation
238 explicit ProcessBlockUsingPixelOperation( PixelOperation &operation, QgsFeedback *feedback )
239 : mOperation( operation )
240 , mFeedback( feedback )
243 typedef void result_type;
245 void operator()( ImageBlock &block )
247 for (
unsigned int y = block.beginLine; y < block.endLine; ++y )
249 if ( mFeedback && mFeedback->isCanceled() )
252 QRgb *ref =
reinterpret_cast< QRgb *
>( block.image->scanLine( y ) );
253 for (
unsigned int x = 0; x < block.lineLength; ++x )
255 mOperation( ref[x], x, y );
260 PixelOperation &mOperation;
261 QgsFeedback *mFeedback =
nullptr;
265 template <
typename LineOperation>
static void runLineOperation( QImage &image, LineOperation &operation, QgsFeedback *feedback =
nullptr );
266 template <
class LineOperation>
static void runLineOperationOnWholeImage( QImage &image, LineOperation &operation, QgsFeedback *feedback =
nullptr );
267 template <
class LineOperation>
268 struct ProcessBlockUsingLineOperation
270 explicit ProcessBlockUsingLineOperation( LineOperation &operation )
271 : mOperation( operation ) { }
273 typedef void result_type;
275 void operator()( ImageBlock &block )
278 int bpl = block.image->bytesPerLine();
279 if ( mOperation.direction() == ByRow )
281 for (
unsigned int y = block.beginLine; y < block.endLine; ++y )
283 QRgb *ref =
reinterpret_cast< QRgb *
>( block.image->scanLine( y ) );
284 mOperation( ref, block.lineLength, bpl );
290 unsigned char *ref = block.image->scanLine( 0 ) + 4 * block.beginLine;
291 for (
unsigned int x = block.beginLine; x < block.endLine; ++x, ref += 4 )
293 mOperation(
reinterpret_cast< QRgb *
>( ref ), block.lineLength, bpl );
298 LineOperation &mOperation;
304 class GrayscalePixelOperation
307 explicit GrayscalePixelOperation(
const GrayscaleMode mode )
311 void operator()( QRgb &rgb,
int x,
int y )
const;
316 static void grayscaleLightnessOp( QRgb &rgb );
317 static void grayscaleLuminosityOp( QRgb &rgb );
318 static void grayscaleAverageOp( QRgb &rgb );
321 class BrightnessContrastPixelOperation
324 BrightnessContrastPixelOperation(
const int brightness,
const double contrast )
325 : mBrightness( brightness )
326 , mContrast( contrast )
329 void operator()( QRgb &rgb,
int x,
int y )
const;
337 class HueSaturationPixelOperation
340 HueSaturationPixelOperation(
const double saturation,
const bool colorize,
341 const int colorizeHue,
const int colorizeSaturation,
342 const double colorizeStrength )
343 : mSaturation( saturation )
344 , mColorize( colorize )
345 , mColorizeHue( colorizeHue )
346 , mColorizeSaturation( colorizeSaturation )
347 , mColorizeStrength( colorizeStrength )
350 void operator()( QRgb &rgb,
int x,
int y )
const;
356 int mColorizeSaturation;
357 double mColorizeStrength;
359 static int adjustColorComponent(
int colorComponent,
int brightness,
double contrastFactor );
362 class MultiplyOpacityPixelOperation
365 explicit MultiplyOpacityPixelOperation(
const double factor )
369 void operator()( QRgb &rgb,
int x,
int y )
const;
375 class ConvertToArrayPixelOperation
378 ConvertToArrayPixelOperation(
const int width,
double *array,
const bool exterior =
true )
381 , mExterior( exterior )
385 void operator()( QRgb &rgb,
int x,
int y );
389 double *mArray =
nullptr;
393 class ShadeFromArrayOperation
396 ShadeFromArrayOperation(
const int width,
double *array,
const double spread,
397 const DistanceTransformProperties &properties )
401 , mProperties( properties )
403 mSpreadSquared = std::pow( mSpread, 2.0 );
406 void operator()( QRgb &rgb,
int x,
int y );
410 double *mArray =
nullptr;
412 double mSpreadSquared;
413 const DistanceTransformProperties &mProperties;
415 static void distanceTransform2d(
double *im,
int width,
int height, QgsFeedback *feedback =
nullptr );
416 static void distanceTransform1d(
double *f,
int n,
int *v,
double *z,
double *d );
417 static double maxValueInDistanceTransformArray(
const double *array,
unsigned int size );
420 class StackBlurLineOperation
423 StackBlurLineOperation(
int alpha, LineOperationDirection direction,
bool forwardDirection,
int i1,
int i2, QgsFeedback *feedback )
425 , mDirection( direction )
426 , mForwardDirection( forwardDirection )
429 , mFeedback( feedback )
432 typedef void result_type;
434 LineOperationDirection direction()
const {
return mDirection; }
436 void operator()( QRgb *startRef,
int lineLength,
int bytesPerLine )
438 if ( mFeedback && mFeedback->isCanceled() )
441 unsigned char *p =
reinterpret_cast< unsigned char *
>( startRef );
443 int increment = ( mDirection == QgsImageOperation::ByRow ) ? 4 : bytesPerLine;
444 if ( !mForwardDirection )
446 p +=
static_cast< std::size_t
>( lineLength - 1 ) * increment;
447 increment = -increment;
450 for (
int i = mi1; i <= mi2; ++i )
456 for (
int j = 1; j < lineLength; ++j, p += increment )
458 if ( mFeedback && mFeedback->isCanceled() )
461 for (
int i = mi1; i <= mi2; ++i )
463 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * mAlpha / 16 ) >> 4;
470 LineOperationDirection mDirection;
471 bool mForwardDirection;
474 QgsFeedback *mFeedback =
nullptr;
477 static double *createGaussianKernel(
int radius );
479 class GaussianBlurOperation
482 GaussianBlurOperation(
int radius, LineOperationDirection direction, QImage *destImage,
double *kernel, QgsFeedback *feedback )
484 , mDirection( direction )
485 , mDestImage( destImage )
486 , mDestImageBpl( destImage->bytesPerLine() )
488 , mFeedback( feedback )
491 typedef void result_type;
493 void operator()( ImageBlock &block );
497 LineOperationDirection mDirection;
498 QImage *mDestImage =
nullptr;
500 double *mKernel =
nullptr;
501 QgsFeedback *mFeedback =
nullptr;
503 inline QRgb gaussianBlurVertical(
int posy,
unsigned char *sourceFirstLine,
int sourceBpl,
int height )
const;
504 inline QRgb gaussianBlurHorizontal(
int posx,
unsigned char *sourceFirstLine,
int width )
const;
510 class FlipLineOperation
513 explicit FlipLineOperation( LineOperationDirection direction )
514 : mDirection( direction )
517 typedef void result_type;
519 LineOperationDirection direction()
const {
return mDirection; }
521 void operator()( QRgb *startRef,
int lineLength,
int bytesPerLine )
const;
524 LineOperationDirection mDirection;