summaryrefslogtreecommitdiff
path: root/libopie2/opieui/oimageeffect.h
Unidiff
Diffstat (limited to 'libopie2/opieui/oimageeffect.h') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opieui/oimageeffect.h558
1 files changed, 558 insertions, 0 deletions
diff --git a/libopie2/opieui/oimageeffect.h b/libopie2/opieui/oimageeffect.h
new file mode 100644
index 0000000..313ea50
--- a/dev/null
+++ b/libopie2/opieui/oimageeffect.h
@@ -0,0 +1,558 @@
1//FIXME: Revise for Opie - do we really need such fancy stuff on PDA's?
2//FIXME: Maybe not on SL5xxx, but surely on C700 :))
3
4/* This file is part of the KDE libraries
5 Copyright (C) 1998, 1999, 2001, 2002 Daniel M. Duley <mosfet@interaccess.com>
6 (C) 1998, 1999 Christian Tibirna <ctibirna@total.net>
7 (C) 1998, 1999 Dirk A. Mueller <mueller@kde.org>
8
9Redistribution and use in source and binary forms, with or without
10modification, are permitted provided that the following conditions
11are met:
12
131. Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
152. Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18
19THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30*/
31
32// $Id$
33
34#ifndef OIMAGEEFFECT_H
35#define OIMAGEEFFECT_H
36
37class QImage;
38class QSize;
39class QColor;
40
41/**
42 * This class includes various @ref QImage based graphical effects.
43 *
44 * Everything is
45 * static, so there is no need to create an instance of this class. You can
46 * just call the static methods. They are encapsulated here merely to provide
47 * a common namespace.
48 */
49
50class OImageEffect
51{
52public:
53 enum GradientType { VerticalGradient, HorizontalGradient,
54 DiagonalGradient, CrossDiagonalGradient,
55 PyramidGradient, RectangleGradient,
56 PipeCrossGradient, EllipticGradient };
57 enum RGBComponent { Red, Green, Blue, Gray, All };
58
59 enum Lighting {NorthLite, NWLite, WestLite, SWLite,
60 SouthLite, SELite, EastLite, NELite};
61
62 enum ModulationType { Intensity, Saturation, HueShift, Contrast };
63
64 enum NoiseType { UniformNoise=0, GaussianNoise, MultiplicativeGaussianNoise,
65 ImpulseNoise, LaplacianNoise, PoissonNoise};
66
67 enum RotateDirection{ Rotate90, Rotate180, Rotate270 };
68
69 /**
70 * Create a gradient from color a to color b of the specified type.
71 *
72 * @param size The desired size of the gradient.
73 * @param ca Color a
74 * @param cb Color b
75 * @param type The type of gradient.
76 * @param ncols The number of colors to use when not running on a
77 * truecolor display. The gradient will be dithered to this number of
78 * colors. Pass 0 to prevent dithering.
79 */
80 static QImage gradient(const QSize &size, const QColor &ca,
81 const QColor &cb, GradientType type, int ncols=3);
82
83 /**
84 * Create an unbalanced gradient.
85
86 * An unbalanced gradient is a gradient where the transition from
87 * color a to color b is not linear, but in this case, exponential.
88 *
89 * @param size The desired size of the gradient.
90 * @param ca Color a
91 * @param cb Color b
92 * @param type The type of gradient.
93 * @param xfactor The x decay length. Use a value between -200 and 200.
94 * @param yfactor The y decay length.
95 * @param ncols The number of colors. See OPixmapEffect:gradient.
96 */
97 static QImage unbalancedGradient(const QSize &size, const QColor &ca,
98 const QColor &cb, GradientType type, int xfactor = 100,
99 int yfactor = 100, int ncols = 3);
100
101 /**
102 * Blends a color into the destination image, using an opacity
103 * value for blending one into another. Very fast direct pixel
104 * manipulation is used.
105 *
106 * @author Karol Szwed (gallium@kde.org)
107 * @param clr source color to be blended into the destination image.
108 * @param dst destination image in which the source will be blended into.
109 * @param opacity opacity (in percent) which determines how much the source
110 * color will be blended into the destination image.
111 * @return The destination image (dst) containing the result.
112 */
113 static QImage& blend(const QColor& clr, QImage& dst, float opacity);
114
115 /**
116 * Blend the src image into the destination image, using an opacity
117 * value for blending one into another. Very fast direct pixel
118 * manipulation is used.
119 *
120 * @author Karol Szwed (gallium@kde.org)
121 * @param src source image to be blended into the destination image.
122 * @param dst destination image in which the source will be blended into.
123 * @param opacity opacity (in percent) which determines how much the source
124 * image will be blended into the destination image.
125 * @return The destination image (dst) containing the result.
126 */
127 static QImage& blend(QImage& src, QImage& dst, float opacity);
128
129 /**
130 * Blend the provided image into a background of the indicated color.
131 *
132 * @param initial_intensity this parameter takes values from -1 to 1:
133 * a) if positive: how much to fade the image in its
134 * less affected spot
135 * b) if negative: roughly indicates how much of the image
136 * remains unaffected
137 * @param bgnd indicates the color of the background to blend in
138 * @param eff lets you choose what kind of blending you like
139 * @param anti_dir blend in the opposite direction (makes no much sense
140 * with concentric blending effects)
141 * @param image must be 32bpp
142 */
143 static QImage& blend(QImage &image, float initial_intensity,
144 const QColor &bgnd, GradientType eff,
145 bool anti_dir=false);
146
147 /**
148 * Blend an image into another one, using a gradient type
149 * for blending from one to another.
150 *
151 * @param image1 source1 and result of blending
152 * @param image2 source2 of blending
153 * @param gt gradient type for blending between source1 and source2
154 * @param xf x decay length for unbalanced gradient tpye
155 * @param yf y decay length for unbalanced gradient tpye
156 */
157 static QImage& blend(QImage &image1,QImage &image2,
158 GradientType gt, int xf=100, int yf=100);
159
160 /**
161 * Blend an image into another one, using a color channel of a
162 * third image for the decision of blending from one to another.
163 *
164 * @param image1 Source 1 and result of blending
165 * @param image2 Source 2 of blending
166 * @param blendImage If the gray value of of pixel is 0, the result
167 * for this pixel is that of image1; for a gray value
168 * of 1, the pixel of image2 is used; for a value
169 * inbetween, a corresponding blending is used.
170 * @param channel The RBG channel to use for the blending decision.
171 */
172 static QImage& blend(QImage &image1, QImage &image2,
173 QImage &blendImage, RGBComponent channel);
174
175 /**
176 * Blend an image into another one, using alpha in the expected way.
177 * @author Rik Hemsley (rikkus) <rik@kde.org>
178 */
179 static bool blend(const QImage & upper, const QImage & lower, QImage & output);
180// Not yet... static bool blend(const QImage & image1, const QImage & image2, QImage & output, const QRect & destRect);
181
182 /**
183 * Blend an image into another one, using alpha in the expected way and
184 * over coordinates @p x and @p y with respect to the lower image.
185 * The output is a QImage which is the @p upper image already blended
186 * with the @p lower one, so its size will be (in general) the same than
187 * @p upper instead of the same size than @p lower like the method above.
188 * In fact, the size of @p output is like upper's one only when it can be
189 * painted on lower, if there has to be some clipping, output's size will
190 * be the clipped area and x and y will be set to the correct up-left corner
191 * where the clipped rectangle begins.
192 */
193 static bool blend(int &x, int &y, const QImage & upper, const QImage & lower, QImage & output);
194 /**
195 * Blend an image into another one, using alpha in the expected way and
196 * over coordinates @p x and @p y with respect to the lower image.
197 * The output is painted in the own @p lower image. This is an optimization
198 * of the blend method above provided by convenience.
199 */
200 static bool blendOnLower(int x, int y, const QImage & upper, const QImage & lower);
201
202 /**
203 * Modifies the intensity of a pixmap's RGB channel component.
204 *
205 * @author Daniel M. Duley (mosfet)
206 * @param image The QImage to process.
207 * @param percent Percent value. Use a negative value to dim.
208 * @param channel Which channel(s) should be modified
209 * @return The @p image, provided for convenience.
210 */
211 static QImage& channelIntensity(QImage &image, float percent,
212 RGBComponent channel);
213
214 /**
215 * Fade an image to a certain background color.
216 *
217 * The number of colors will not be changed.
218 *
219 * @param image The QImage to process.
220 * @param val The strength of the effect. 0 <= val <= 1.
221 * @param color The background color.
222 * @return Returns the @ref image(), provided for convenience.
223 */
224 static QImage& fade(QImage &img, float val, const QColor &color);
225
226
227 /**
228 * This recolors a pixmap. The most dark color will become color a,
229 * the most bright one color b, and in between.
230 *
231 * @param image A QImage to process.
232 * @param ca Color a
233 * @param cb Color b
234 */
235 static QImage& flatten(QImage &image, const QColor &ca,
236 const QColor &cb, int ncols=0);
237
238 /**
239 * Build a hash on any given @ref QImage
240 *
241 * @param image The QImage to process
242 * @param lite The hash faces the indicated lighting (cardinal poles).
243 * @param spacing How many unmodified pixels inbetween hashes.
244 * @return Returns the @ref image(), provided for convenience.
245 */
246 static QImage& hash(QImage &image, Lighting lite=NorthLite,
247 unsigned int spacing=0);
248
249 /**
250 * Either brighten or dim the image by a specified percent.
251 * For example, .50 will modify the colors by 50%.
252 *
253 * @author Daniel M. Duley (mosfet)
254 * @param image The QImage to process.
255 * @param percent The percent value. Use a negative value to dim.
256 * @return Returns The @ref image(), provided for convenience.
257 */
258 static QImage& intensity(QImage &image, float percent);
259
260 /**
261 * Modulate the image with a color channel of another image.
262 *
263 * @param image The QImage to modulate and result.
264 * @param modImage The QImage to use for modulation.
265 * @param reverse Invert the meaning of image/modImage; result is image!
266 * @param type The modulation Type to use.
267 * @param factor The modulation amplitude; with 0 no effect [-200;200].
268 * @param channel The RBG channel of image2 to use for modulation.
269 * @return Returns the @ref image(), provided for convenience.
270 */
271 static QImage& modulate(QImage &image, QImage &modImage, bool reverse,
272 ModulationType type, int factor, RGBComponent channel);
273
274 /**
275 * Convert an image to grayscale.
276 *
277 * @author Daniel M. Duley (mosfet)
278 * @param image The @ref QImage to process.
279 * @param fast Set to @p true in order to use a faster but non-photographic
280 * quality algorithm. Appropriate for things such as toolbar icons.
281 * @return Returns the @ref image(), provided for convenience.
282 */
283 static QImage& toGray(QImage &image, bool fast = false);
284
285 /**
286 * Desaturate an image evenly.
287 *
288 * @param image The QImage to process.
289 * @param desat A value between 0 and 1 setting the degree of desaturation
290 * @return Returns the @ref image(), provided for convenience.
291 */
292 static QImage& desaturate(QImage &image, float desat = 0.3);
293
294 /**
295 * Fast, but low quality contrast of an image. Also see contrastHSV.
296 *
297 * @author Daniel M. Duley (mosfet)
298 * @param image The QImage to process.
299 * @param c A contrast value between -255 to 255.
300 * @return The @ref image(), provided for convenience.
301 */
302 static QImage& contrast(QImage &image, int c);
303
304 /**
305 * Dither an image using Floyd-Steinberg dithering for low-color
306 * situations.
307 *
308 * @param image The QImage to process.
309 * @param palette The color palette to use
310 * @param size The size of the palette
311 * @return Returns the @ref image(), provided for convenience.
312 */
313 static QImage& dither(QImage &img, const QColor *palette, int size);
314
315 /**
316 * Calculate the image for a selected image, for instance a selected icon
317 * on the desktop.
318 * @param img the QImage to select
319 * @param col the selected color, usually from QColorGroup::highlight().
320 */
321 static QImage& selectedImage( QImage &img, const QColor &col );
322
323 /**
324 * High quality, expensive HSV contrast. You can do a faster one by just
325 * taking a intensity threshold (ie: 128) and incrementing RGB color
326 * channels above it and decrementing those below it, but this gives much
327 * better results.
328 *
329 * @author Daniel M. Duley (mosfet)
330 * @param img The QImage to process.
331 * @param sharpen If true sharpness is increase, (spiffed). Otherwise
332 * it is decreased, (dulled).
333 */
334 static void contrastHSV(QImage &img, bool sharpen=true);
335
336 /**
337 * Normalizes the pixel values to span the full range of color values.
338 * This is a contrast enhancement technique.
339 * @author Daniel M. Duley (mosfet)
340 */
341 static void normalize(QImage &img);
342
343 /**
344 * Performs histogram equalization on the reference
345 * image.
346 * @author Daniel M. Duley (mosfet)
347 */
348 static void equalize(QImage &img);
349
350 /**
351 * Thresholds the reference image. You can also threshold images by using
352 * ThresholdDither in the various QPixmap/QImage convert methods, but this
353 * lets you specify a threshold value.
354 *
355 * @author Daniel M. Duley (mosfet)
356 * @param img The QImage to process.
357 * @param value The threshold value.
358 */
359 static void threshold(QImage &img, unsigned int value=128);
360
361 /**
362 * Produces a 'solarization' effect seen when exposing a photographic
363 * film to light during the development process.
364 *
365 * @author Daniel M. Duley (mosfet)
366 * @param img The QImage to process.
367 * @param factor The extent of the solarization (0-99.9)
368 */
369 static void solarize(QImage &img, double factor=50.0);
370
371 /**
372 * Embosses the source image. This involves highlighting the edges
373 * and applying various other enhancements in order to get a metal
374 * effect.
375 *
376 * @author Daniel M. Duley (mosfet)
377 * @param src The QImage to process.
378 * @return The embossed image. The original is not changed.
379 */
380 static QImage emboss(QImage &src);
381
382 /**
383 * Minimizes speckle noise in the source image using the 8 hull
384 * algorithm.
385 *
386 * @author Daniel M. Duley (mosfet)
387 * @param src The QImage to process.
388 * @return The despeckled image. The original is not changed.
389 */
390 static QImage despeckle(QImage &src);
391
392 /**
393 * Produces a neat little "charcoal" effect.
394 *
395 * @author Daniel M. Duley (mosfet)
396 * @param src The QImage to process.
397 * @param factor The factor for detecting lines (0-99.0).
398 * @return The charcoal image. The original is not changed.
399 */
400 static QImage charcoal(QImage &src, double factor=50.0);
401
402 /**
403 * Rotates the image by the specified amount
404 *
405 * @author Daniel M. Duley (mosfet)
406 * @param src The QImage to process.
407 * @param r The rotate direction.
408 * @return The rotated image. The original is not changed.
409 */
410 static QImage rotate(QImage &src, RotateDirection r);
411
412 /**
413 * Scales an image using simple pixel sampling. This does not produce
414 * nearly as nice a result as QImage::smoothScale(), but has the
415 * advantage of being much faster - only a few milliseconds.
416 *
417 * @author Daniel M. Duley (mosfet)
418 * @param src The QImage to process.
419 * @param w The new width.
420 * @param h The new height.
421 * @return The scaled image. The original is not changed.
422 */
423 static QImage sample(QImage &src, int w, int h);
424
425 /**
426 * Adds noise to an image.
427 *
428 * @author Daniel M. Duley (mosfet)
429 * @param src The QImage to process.
430 * @param type The algorithm used to generate the noise.
431 * @return The image with noise added. The original is not changed.
432 */
433 static QImage addNoise(QImage &src, NoiseType type = GaussianNoise);
434
435 /**
436 * Blurs an image by convolving pixel neighborhoods.
437 *
438 * @author Daniel M. Duley (mosfet)
439 * @param src The QImage to process.
440 * @param factor The percent weight to give to the center pixel.
441 * @return The blurred image. The original is not changed.
442 */
443 static QImage blur(QImage &src, double factor=50.0);
444
445 /**
446 * Detects edges in an image using pixel neighborhoods and an edge
447 * detection mask.
448 *
449 * @author Daniel M. Duley (mosfet)
450 * @param src The QImage to process.
451 * @param factor The percent weight to give to the center pixel.
452 * @return The image with edges detected. The original is not changed.
453 */
454 static QImage edge(QImage &src, double factor=50.0);
455
456 /**
457 * Implodes an image by a specified percent.
458 *
459 * @author Daniel M. Duley (mosfet)
460 * @param src The QImage to process.
461 * @param factor The extent of the implosion.
462 * @param background An RGBA value to use for the background. After the
463 * effect some pixels may be "empty". This value is used for those pixels.
464 * @return The imploded image. The original is not changed.
465 */
466 static QImage implode(QImage &src, double factor=30.0,
467 unsigned int background = 0xFFFFFFFF);
468 /**
469 * Produces an oil painting effect.
470 *
471 * @author Daniel M. Duley (mosfet)
472 * @param src The QImage to process.
473 * @param radius The radius of the pixel neighborhood used in applying the
474 * effect.
475 * @return The new image. The original is not changed.
476 */
477 static QImage oilPaint(QImage &src, int radius=3);
478
479 /**
480 * Sharpens the pixels in the image using pixel neighborhoods.
481 *
482 * @author Daniel M. Duley (mosfet)
483 * @param src The QImage to process.
484 * @param factor The percent weight to give to the center pixel.
485 * @return The sharpened image. The original is not changed.
486 */
487 static QImage sharpen(QImage &src, double factor=30.0);
488
489 /**
490 * Randomly displaces pixels.
491 *
492 * @author Daniel M. Duley (mosfet)
493 * @param src The QImage to process.
494 * @param amount The vicinity for choosing a random pixel to swap.
495 * @return The image with pixels displaced. The original is not changed.
496 */
497 static QImage spread(QImage &src, unsigned int amount=3);
498
499 /**
500 * Shades the image using a distance light source.
501 *
502 * @author Daniel M. Duley (mosfet)
503 * @param src The QImage to process.
504 * @param color_shading If true do color shading, otherwise do grayscale.
505 * @param azimuth Determines the light source and direction.
506 * @param elevation Determines the light source and direction.
507 * @return The shaded image. The original is not changed.
508 */
509 static QImage shade(QImage &src, bool color_shading=true, double azimuth=30.0,
510 double elevation=30.0);
511 /**
512 * Swirls the image by a specified amount
513 *
514 * @author Daniel M. Duley (mosfet)
515 * @param src The QImage to process.
516 * @param degrees The tightness of the swirl.
517 * @param background An RGBA value to use for the background. After the
518 * effect some pixels may be "empty". This value is used for those pixels.
519 * @return The swirled image. The original is not changed.
520 */
521 static QImage swirl(QImage &src, double degrees=50.0, unsigned int background =
522 0xFFFFFFFF);
523
524 /**
525 * Modifies the pixels along a sine wave.
526 *
527 * @author Daniel M. Duley (mosfet)
528 * @param src The QImage to process.
529 * @param amplitude The amplitude of the sine wave.
530 * @param wavelength The frequency of the sine wave.
531 * @return The new image. The original is not changed.
532 */
533 static QImage wave(QImage &src, double amplitude=25.0, double frequency=150.0,
534 unsigned int background = 0xFFFFFFFF);
535
536private:
537
538 /**
539 * Helper function to fast calc some altered (lighten, shaded) colors
540 *
541 */
542 static unsigned int lHash(unsigned int c);
543 static unsigned int uHash(unsigned int c);
544
545 /**
546 * Helper function to find the nearest color to the RBG triplet
547 */
548 static int nearestColor( int r, int g, int b, const QColor *pal, int size );
549
550 static void hull(const int x_offset, const int y_offset, const int polarity,
551 const int width, const int height,
552 unsigned int *f, unsigned int *g);
553 static unsigned int generateNoise(unsigned int pixel, NoiseType type);
554 static unsigned int interpolateColor(QImage *image, double x, double y,
555 unsigned int background);
556};
557
558#endif