1
/* ============================================================
3
* This file is a part of digiKam project
4
* http://www.digikam.org
7
* Description : Distortion FX threaded image filter.
9
* Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
10
* Copyright (C) 2006-2007 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
12
* Original Distortion algorithms copyrighted 2004-2005 by
13
* Pieter Z. Voloshyn <pieter dot voloshyn at gmail dot com>.
15
* This program is free software; you can redistribute it
16
* and/or modify it under the terms of the GNU General
17
* Public License as published by the Free Software Foundation;
18
* either version 2, or (at your option)
21
* This program is distributed in the hope that it will be useful,
22
* but WITHOUT ANY WARRANTY; without even the implied warranty of
23
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
* GNU General Public License for more details.
26
* ============================================================ */
29
#define ANGLE_RATIO 0.017453292519943295769236907685
32
#include "distortionfx.h"
46
#include "dimgimagefilters.h"
48
namespace DigikamDistortionFXImagesPlugin
51
DistortionFX::DistortionFX(Digikam::DImg *orgImage, QObject *parent, int effectType,
52
int level, int iteration, bool antialiasing)
53
: Digikam::DImgThreadedFilter(orgImage, parent, "DistortionFX")
55
m_effectType = effectType;
57
m_iteration = iteration;
58
m_antiAlias = antialiasing;
63
void DistortionFX::filterImage(void)
65
int w = m_orgImage.width();
66
int h = m_orgImage.height();
73
fisheye(&m_orgImage, &m_destImage, (double)(l/5.0), m_antiAlias);
77
twirl(&m_orgImage, &m_destImage, l, m_antiAlias);
81
cilindrical(&m_orgImage, &m_destImage, (double)l, true, false, m_antiAlias);
85
cilindrical(&m_orgImage, &m_destImage, (double)l, false, true, m_antiAlias);
89
cilindrical(&m_orgImage, &m_destImage, (double)l, true, true, m_antiAlias);
93
fisheye(&m_orgImage, &m_destImage, (double)(-l/5.0), m_antiAlias);
97
multipleCorners(&m_orgImage, &m_destImage, l, m_antiAlias);
100
case WavesHorizontal:
101
waves(&m_orgImage, &m_destImage, l, f, true, true);
105
waves(&m_orgImage, &m_destImage, l, f, true, false);
109
blockWaves(&m_orgImage, &m_destImage, l, f, false);
113
blockWaves(&m_orgImage, &m_destImage, l, f, true);
117
circularWaves(&m_orgImage, &m_destImage, w/2, h/2, (double)l, (double)f, 0.0, false, m_antiAlias);
121
circularWaves(&m_orgImage, &m_destImage, w/2, h/2, (double)l, (double)f, 25.0, true, m_antiAlias);
124
case PolarCoordinates:
125
polarCoordinates(&m_orgImage, &m_destImage, true, m_antiAlias);
128
case UnpolarCoordinates:
129
polarCoordinates(&m_orgImage, &m_destImage, false, m_antiAlias);
133
tile(&m_orgImage, &m_destImage, 200-f, 200-f, l);
139
This code is shared by six methods.
140
Write value of pixel w|h in data to pixel nw|nh in pResBits.
141
Antialias if requested.
143
void DistortionFX::setPixelFromOther(int Width, int Height, bool sixteenBit, int bytesDepth,
144
uchar *data, uchar *pResBits,
145
int w, int h, double nw, double nh, bool AntiAlias)
147
Digikam::DColor color;
148
int offset, offsetOther;
150
offset = getOffset(Width, w, h, bytesDepth);
154
uchar *ptr = pResBits + offset;
157
unsigned short *ptr16 = (unsigned short *)ptr;
158
Digikam::DImgImageFilters().pixelAntiAliasing16((unsigned short *)data, Width, Height, nw, nh,
159
ptr16+3, ptr16+2, ptr16+1, ptr16);
163
Digikam::DImgImageFilters().pixelAntiAliasing(data, Width, Height, nw, nh,
164
ptr+3, ptr+2, ptr+1, ptr);
169
// we get the position adjusted
170
offsetOther = getOffsetAdjusted(Width, Height, (int)nw, (int)nh, bytesDepth);
172
color.setColor(data + offsetOther, sixteenBit);
173
// write color to destination
174
color.setPixel(pResBits + offset);
178
/* Function to apply the fisheye effect backported from ImageProcessing version 2
180
* data => The image data in RGBA mode.
181
* Width => Width of image.
182
* Height => Height of image.
183
* Coeff => Distortion effect coeff. Positive value render 'Fish Eyes' effect,
184
* and negative values render 'Caricature' effect.
185
* Antialias => Smart blurring result.
187
* Theory => This is a great effect if you take employee photos
188
* Its pure trigonometry. I think if you study hard the code you
189
* understand very well.
191
void DistortionFX::fisheye(Digikam::DImg *orgImage, Digikam::DImg *destImage, double Coeff, bool AntiAlias)
193
if (Coeff == 0.0) return;
195
int Width = orgImage->width();
196
int Height = orgImage->height();
197
uchar* data = orgImage->bits();
198
bool sixteenBit = orgImage->sixteenBit();
199
int bytesDepth = orgImage->bytesDepth();
200
uchar* pResBits = destImage->bits();
203
double nh, nw, th, tw;
206
int nHalfW = Width / 2, nHalfH = Height / 2;
208
Digikam::DColor color;
211
double lfXScale = 1.0, lfYScale = 1.0;
212
double lfRadius, lfRadMax, lfAngle, lfCoeff, lfCoeffStep = Coeff / 1000.0;
215
lfYScale = (double)Width / (double)Height;
216
else if (Height > Width)
217
lfXScale = (double)Height / (double)Width;
219
lfRadMax = (double)qMax(Height, Width) / 2.0;
220
lfCoeff = lfRadMax / log (fabs (lfCoeffStep) * lfRadMax + 1.0);
224
for (h = 0; !m_cancel && (h < Height); ++h)
226
th = lfYScale * (double)(h - nHalfH);
228
for (w = 0; !m_cancel && (w < Width); ++w)
230
tw = lfXScale * (double)(w - nHalfW);
232
// we find the distance from the center
233
lfRadius = sqrt (th * th + tw * tw);
235
if (lfRadius < lfRadMax)
237
lfAngle = atan2 (th, tw);
240
lfRadius = (exp (lfRadius / lfCoeff) - 1.0) / lfCoeffStep;
242
lfRadius = lfCoeff * log (1.0 + (-1.0 * lfCoeffStep) * lfRadius);
244
nw = (double)nHalfW + (lfRadius / lfXScale) * cos (lfAngle);
245
nh = (double)nHalfH + (lfRadius / lfYScale) * sin (lfAngle);
247
setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, h, nw, nh, AntiAlias);
252
offset = getOffset(Width, w, h, bytesDepth);
253
color.setColor(data + offset, sixteenBit);
254
color.setPixel(pResBits + offset);
258
// Update the progress bar in dialog.
259
progress = (int) (((double)(h) * 100.0) / Height);
262
postProgress(progress);
266
/* Function to apply the twirl effect backported from ImageProcessing version 2
268
* data => The image data in RGBA mode.
269
* Width => Width of image.
270
* Height => Height of image.
271
* Twirl => Distance value.
272
* Antialias => Smart blurring result.
274
* Theory => Take spiral studies, you will understand better, I'm studying
275
* hard on this effect, because it is not too fast.
277
void DistortionFX::twirl(Digikam::DImg *orgImage, Digikam::DImg *destImage, int Twirl, bool AntiAlias)
279
// if twirl value is zero, we do nothing
284
int Width = orgImage->width();
285
int Height = orgImage->height();
286
uchar* data = orgImage->bits();
287
bool sixteenBit = orgImage->sixteenBit();
288
int bytesDepth = orgImage->bytesDepth();
289
uchar* pResBits = destImage->bits();
292
double tw, th, nh, nw;
294
Digikam::DColor color;
298
int nHalfW = Width / 2, nHalfH = Height / 2;
300
double lfXScale = 1.0, lfYScale = 1.0;
301
double lfAngle, lfNewAngle, lfAngleStep, lfAngleSum, lfCurrentRadius, lfRadMax;
304
lfYScale = (double)Width / (double)Height;
305
else if (Height > Width)
306
lfXScale = (double)Height / (double)Width;
308
// the angle step is twirl divided by 10000
309
lfAngleStep = Twirl / 10000.0;
310
// now, we get the minimum radius
311
lfRadMax = (double)qMax(Width, Height) / 2.0;
315
for (h = 0; !m_cancel && (h < Height); ++h)
317
th = lfYScale * (double)(h - nHalfH);
319
for (w = 0; !m_cancel && (w < Width); ++w)
321
tw = lfXScale * (double)(w - nHalfW);
323
// now, we get the distance
324
lfCurrentRadius = sqrt (th * th + tw * tw);
326
// if distance is less than maximum radius...
327
if (lfCurrentRadius < lfRadMax)
329
// we find the angle from the center
330
lfAngle = atan2 (th, tw);
331
// we get the accumuled angle
332
lfAngleSum = lfAngleStep * (-1.0 * (lfCurrentRadius - lfRadMax));
333
// ok, we sum angle with accumuled to find a new angle
334
lfNewAngle = lfAngle + lfAngleSum;
336
// now we find the exact position's x and y
337
nw = (double)nHalfW + cos (lfNewAngle) * (lfCurrentRadius / lfXScale);
338
nh = (double)nHalfH + sin (lfNewAngle) * (lfCurrentRadius / lfYScale);
340
setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, h, nw, nh, AntiAlias);
345
offset = getOffset(Width, w, h, bytesDepth);
346
color.setColor(data + offset, sixteenBit);
347
color.setPixel(pResBits + offset);
351
// Update the progress bar in dialog.
352
progress = (int) (((double)h * 100.0) / Height);
355
postProgress(progress);
359
/* Function to apply the Cilindrical effect backported from ImageProcessing version 2
361
* data => The image data in RGBA mode.
362
* Width => Width of image.
363
* Height => Height of image.
364
* Coeff => Cilindrical value.
365
* Horizontal => Apply horizontally.
366
* Vertical => Apply vertically.
367
* Antialias => Smart blurring result.
369
* Theory => This is a great effect, similar to Spherize (Photoshop).
370
* If you understand FishEye, you will understand Cilindrical
371
* FishEye apply a logarithm function using a sphere radius,
372
* Spherize use the same function but in a rectangular
375
void DistortionFX::cilindrical(Digikam::DImg *orgImage, Digikam::DImg *destImage, double Coeff,
376
bool Horizontal, bool Vertical, bool AntiAlias)
379
if ((Coeff == 0.0) || (! (Horizontal || Vertical)))
382
int Width = orgImage->width();
383
int Height = orgImage->height();
384
uchar* data = orgImage->bits();
385
bool sixteenBit = orgImage->sixteenBit();
386
int bytesDepth = orgImage->bytesDepth();
387
uchar* pResBits = destImage->bits();
394
int nHalfW = Width / 2, nHalfH = Height / 2;
395
double lfCoeffX = 1.0, lfCoeffY = 1.0, lfCoeffStep = Coeff / 1000.0;
398
lfCoeffX = (double)nHalfW / log (fabs (lfCoeffStep) * nHalfW + 1.0);
400
lfCoeffY = (double)nHalfH / log (fabs (lfCoeffStep) * nHalfH + 1.0);
403
memcpy (pResBits, data, orgImage->numBytes());
407
for (h = 0; !m_cancel && (h < Height); ++h)
409
for (w = 0; !m_cancel && (w < Width); ++w)
411
// we find the distance from the center
412
nh = fabs ((double)(h - nHalfH));
413
nw = fabs ((double)(w - nHalfW));
418
nw = (exp (nw / lfCoeffX) - 1.0) / lfCoeffStep;
420
nw = lfCoeffX * log (1.0 + (-1.0 * lfCoeffStep) * nw);
426
nh = (exp (nh / lfCoeffY) - 1.0) / lfCoeffStep;
428
nh = lfCoeffY * log (1.0 + (-1.0 * lfCoeffStep) * nh);
431
nw = (double)nHalfW + ((w >= nHalfW) ? nw : -nw);
432
nh = (double)nHalfH + ((h >= nHalfH) ? nh : -nh);
434
setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, h, nw, nh, AntiAlias);
437
// Update the progress bar in dialog.
438
progress = (int) (((double)h * 100.0) / Height);
441
postProgress(progress);
445
/* Function to apply the Multiple Corners effect backported from ImageProcessing version 2
447
* data => The image data in RGBA mode.
448
* Width => Width of image.
449
* Height => Height of image.
450
* Factor => nb corners.
451
* Antialias => Smart blurring result.
453
* Theory => This is an amazing function, you've never seen this before.
454
* I was testing some trigonometric functions, and I saw that if
455
* I multiply the angle by 2, the result is an image like this
456
* If we multiply by 3, we can create the SixCorners effect.
458
void DistortionFX::multipleCorners(Digikam::DImg *orgImage, Digikam::DImg *destImage, int Factor, bool AntiAlias)
460
if (Factor == 0) return;
462
int Width = orgImage->width();
463
int Height = orgImage->height();
464
uchar* data = orgImage->bits();
465
bool sixteenBit = orgImage->sixteenBit();
466
int bytesDepth = orgImage->bytesDepth();
467
uchar* pResBits = destImage->bits();
473
int nHalfW = Width / 2, nHalfH = Height / 2;
474
double lfAngle, lfNewRadius, lfCurrentRadius, lfRadMax;
476
lfRadMax = sqrt (Height * Height + Width * Width) / 2.0;
480
for (h = 0; !m_cancel && (h < Height); ++h)
482
for (w = 0; !m_cancel && (w < Width); ++w)
484
// we find the distance from the center
488
// now, we get the distance
489
lfCurrentRadius = sqrt (nh * nh + nw * nw);
490
// we find the angle from the center
491
lfAngle = atan2 (nh, nw) * (double)Factor;
493
// ok, we sum angle with accumuled to find a new angle
494
lfNewRadius = lfCurrentRadius * lfCurrentRadius / lfRadMax;
496
// now we find the exact position's x and y
497
nw = (double)nHalfW - (cos (lfAngle) * lfNewRadius);
498
nh = (double)nHalfH - (sin (lfAngle) * lfNewRadius);
500
setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, h, nw, nh, AntiAlias);
503
// Update the progress bar in dialog.
504
progress = (int) (((double)h * 100.0) / Height);
507
postProgress(progress);
511
/* Function to apply the Polar Coordinates effect backported from ImageProcessing version 2
513
* data => The image data in RGBA mode.
514
* Width => Width of image.
515
* Height => Height of image.
516
* Type => if true Polar Coordinate to Polar else inverse.
517
* Antialias => Smart blurring result.
519
* Theory => Similar to PolarCoordinates from Photoshop. We apply the polar
520
* transformation in a proportional (Height and Width) radius.
522
void DistortionFX::polarCoordinates(Digikam::DImg *orgImage, Digikam::DImg *destImage, bool Type, bool AntiAlias)
524
int Width = orgImage->width();
525
int Height = orgImage->height();
526
uchar* data = orgImage->bits();
527
bool sixteenBit = orgImage->sixteenBit();
528
int bytesDepth = orgImage->bytesDepth();
529
uchar* pResBits = destImage->bits();
532
double nh, nw, th, tw;
535
int nHalfW = Width / 2, nHalfH = Height / 2;
536
double lfXScale = 1.0, lfYScale = 1.0;
537
double lfAngle, lfRadius, lfRadMax;
540
lfYScale = (double)Width / (double)Height;
541
else if (Height > Width)
542
lfXScale = (double)Height / (double)Width;
544
lfRadMax = (double)qMax(Height, Width) / 2.0;
548
for (h = 0; !m_cancel && (h < Height); ++h)
550
th = lfYScale * (double)(h - nHalfH);
552
for (w = 0; !m_cancel && (w < Width); ++w)
554
tw = lfXScale * (double)(w - nHalfW);
558
// now, we get the distance
559
lfRadius = sqrt (th * th + tw * tw);
560
// we find the angle from the center
561
lfAngle = atan2 (tw, th);
563
// now we find the exact position's x and y
564
nh = lfRadius * (double) Height / lfRadMax;
565
nw = lfAngle * (double) Width / (2 * M_PI);
567
nw = (double)nHalfW + nw;
571
lfRadius = (double)(h) * lfRadMax / (double)Height;
572
lfAngle = (double)(w) * (2 * M_PI) / (double) Width;
574
nw = (double)nHalfW - (lfRadius / lfXScale) * sin (lfAngle);
575
nh = (double)nHalfH - (lfRadius / lfYScale) * cos (lfAngle);
578
setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, h, nw, nh, AntiAlias);
581
// Update the progress bar in dialog.
582
progress = (int) (((double)h * 100.0) / Height);
585
postProgress(progress);
589
/* Function to apply the circular waves effect backported from ImageProcessing version 2
591
* data => The image data in RGBA mode.
592
* Width => Width of image.
593
* Height => Height of image.
594
* X, Y => Position of circle center on the image.
595
* Amplitude => Sinoidal maximum height
596
* Frequency => Frequency value.
597
* Phase => Phase value.
598
* WavesType => If true the amplitude is proportional to radius.
599
* Antialias => Smart bluring result.
601
* Theory => Similar to Waves effect, but here I apply a senoidal function
602
* with the angle point.
604
void DistortionFX::circularWaves(Digikam::DImg *orgImage, Digikam::DImg *destImage, int X, int Y, double Amplitude,
605
double Frequency, double Phase, bool WavesType, bool AntiAlias)
607
if (Amplitude < 0.0) Amplitude = 0.0;
608
if (Frequency < 0.0) Frequency = 0.0;
610
int Width = orgImage->width();
611
int Height = orgImage->height();
612
uchar* data = orgImage->bits();
613
bool sixteenBit = orgImage->sixteenBit();
614
int bytesDepth = orgImage->bytesDepth();
615
uchar* pResBits = destImage->bits();
621
double lfRadius, lfRadMax, lfNewAmp = Amplitude;
622
double lfFreqAngle = Frequency * ANGLE_RATIO;
624
Phase *= ANGLE_RATIO;
626
lfRadMax = sqrt (Height * Height + Width * Width);
628
for (h = 0; !m_cancel && (h < Height); ++h)
630
for (w = 0; !m_cancel && (w < Width); ++w)
635
lfRadius = sqrt (nw * nw + nh * nh);
638
lfNewAmp = Amplitude * lfRadius / lfRadMax;
640
nw = (double)w + lfNewAmp * sin(lfFreqAngle * lfRadius + Phase);
641
nh = (double)h + lfNewAmp * cos(lfFreqAngle * lfRadius + Phase);
643
setPixelFromOther(Width, Height, sixteenBit, bytesDepth, data, pResBits, w, h, nw, nh, AntiAlias);
646
// Update the progress bar in dialog.
647
progress = (int) (((double)h * 100.0) / Height);
650
postProgress(progress);
654
/* Function to apply the waves effect
656
* data => The image data in RGBA mode.
657
* Width => Width of image.
658
* Height => Height of image.
659
* Amplitude => Sinoidal maximum height.
660
* Frequency => Frequency value.
661
* FillSides => Like a boolean variable.
662
* Direction => Vertical or horizontal flag.
664
* Theory => This is an amazing effect, very funny, and very simple to
665
* understand. You just need understand how sin and cos works.
667
void DistortionFX::waves(Digikam::DImg *orgImage, Digikam::DImg *destImage,
668
int Amplitude, int Frequency,
669
bool FillSides, bool Direction)
671
if (Amplitude < 0) Amplitude = 0;
672
if (Frequency < 0) Frequency = 0;
674
int Width = orgImage->width();
675
int Height = orgImage->height();
680
if (Direction) // Horizontal
684
for (h = 0; !m_cancel && (h < Height); ++h)
686
tx = lround(Amplitude * sin ((Frequency * 2) * h * (M_PI / 180)));
687
destImage->bitBltImage(orgImage, 0, h, Width, 1, tx, h);
691
destImage->bitBltImage(orgImage, Width - tx, h, tx, 1, 0, h);
692
destImage->bitBltImage(orgImage, 0, h, Width - (Width - 2 * Amplitude + tx), 1, Width + tx, h);
695
// Update the progress bar in dialog.
696
progress = (int) (((double)h * 100.0) / Height);
699
postProgress(progress);
706
for (w = 0; !m_cancel && (w < Width); ++w)
708
ty = lround(Amplitude * sin ((Frequency * 2) * w * (M_PI / 180)));
709
destImage->bitBltImage(orgImage, w, 0, 1, Height, w, ty);
713
destImage->bitBltImage(orgImage, w, Height - ty, 1, ty, w, 0);
714
destImage->bitBltImage(orgImage, w, 0, 1, Height - (Height - 2 * Amplitude + ty), w, Height + ty);
717
// Update the progress bar in dialog.
718
progress = (int) (((double)w * 100.0) / Width);
721
postProgress(progress);
726
/* Function to apply the block waves effect
728
* data => The image data in RGBA mode.
729
* Width => Width of image.
730
* Height => Height of image.
731
* Amplitude => Sinoidal maximum height
732
* Frequency => Frequency value
733
* Mode => The mode to be applied.
735
* Theory => This is an amazing effect, very funny when amplitude and
736
* frequency are small values.
738
void DistortionFX::blockWaves(Digikam::DImg *orgImage, Digikam::DImg *destImage,
739
int Amplitude, int Frequency, bool Mode)
741
if (Amplitude < 0) Amplitude = 0;
742
if (Frequency < 0) Frequency = 0;
744
int Width = orgImage->width();
745
int Height = orgImage->height();
746
uchar* data = orgImage->bits();
747
bool sixteenBit = orgImage->sixteenBit();
748
int bytesDepth = orgImage->bytesDepth();
749
uchar* pResBits = destImage->bits();
751
int nw, nh, progress;
754
Digikam::DColor color;
755
int offset, offsetOther;
757
int nHalfW = Width / 2, nHalfH = Height / 2;
759
for (int w = 0; !m_cancel && (w < Width); ++w)
761
for (int h = 0; !m_cancel && (h < Height); ++h)
766
Radius = sqrt (nw * nw + nh * nh);
770
nw = (int)(w + Amplitude * sin (Frequency * nw * (M_PI / 180)));
771
nh = (int)(h + Amplitude * cos (Frequency * nh * (M_PI / 180)));
775
nw = (int)(w + Amplitude * sin (Frequency * w * (M_PI / 180)));
776
nh = (int)(h + Amplitude * cos (Frequency * h * (M_PI / 180)));
779
offset = getOffset(Width, w, h, bytesDepth);
780
offsetOther = getOffsetAdjusted(Width, Height, (int)nw, (int)nh, bytesDepth);
783
color.setColor(data + offsetOther, sixteenBit);
784
// write color to destination
785
color.setPixel(pResBits + offset);
788
// Update the progress bar in dialog.
789
progress = (int) (((double)w * 100.0) / Width);
792
postProgress(progress);
796
/* Function to apply the tile effect
798
* data => The image data in RGBA mode.
799
* Width => Width of image.
800
* Height => Height of image.
801
* WSize => Tile Width
802
* HSize => Tile Height
803
* Random => Maximum random value
805
* Theory => Similar to Tile effect from Photoshop and very easy to
806
* understand. We get a rectangular area using WSize and HSize and
807
* replace in a position with a random distance from the original
810
void DistortionFX::tile(Digikam::DImg *orgImage, Digikam::DImg *destImage,
811
int WSize, int HSize, int Random)
813
if (WSize < 1) WSize = 1;
814
if (HSize < 1) HSize = 1;
815
if (Random < 1) Random = 1;
817
int Width = orgImage->width();
818
int Height = orgImage->height();
820
QDateTime dt = QDateTime::currentDateTime();
821
QDateTime Y2000( QDate(2000, 1, 1), QTime(0, 0, 0) );
822
uint seed = dt.secsTo(Y2000);
827
int tx, ty, h, w, progress;
829
for (h = 0; !m_cancel && (h < Height); h += HSize)
831
for (w = 0; !m_cancel && (w < Width); w += WSize)
834
tx = (int)(rand_r(&seed) % Random) - (Random / 2);
835
ty = (int)(rand_r(&seed) % Random) - (Random / 2);
837
tx = (int)(rand() % Random) - (Random / 2);
838
ty = (int)(rand() % Random) - (Random / 2);
840
destImage->bitBltImage(orgImage, w, h, WSize, HSize, w + tx, h + ty);
843
// Update the progress bar in dialog.
844
progress = (int)(((double)h * 100.0) / Height);
847
postProgress(progress);
852
/* Function to return the maximum radius with a determined angle
854
* Height => Height of the image
855
* Width => Width of the image
856
* Angle => Angle to analyze the maximum radius
858
* Theory => This function calculates the maximum radius to that angle
859
* so, we can build an oval circumference
862
double DistortionFX::maximumRadius(int Height, int Width, double Angle)
864
double MaxRad, MinRad;
865
double Radius, DegAngle = fabs (Angle * 57.295); // Rads -> Degrees
867
MinRad = qMin (Height, Width) / 2.0; // Gets the minor radius
868
MaxRad = qMax (Height, Width) / 2.0; // Gets the major radius
870
// Find the quadrant between -PI/2 and PI/2
872
Radius = proportionalValue (MinRad, MaxRad, (DegAngle * (255.0 / 90.0)));
874
Radius = proportionalValue (MaxRad, MinRad, ((DegAngle - 90.0) * (255.0 / 90.0)));
879
} // namespace DigikamDistortionFXImagesPlugin