From 796975bd9db8f4c1c2e34d28cbd151392637f13e Mon Sep 17 00:00:00 2001 From: twanvl Date: Sun, 30 Dec 2007 00:48:39 +0000 Subject: [PATCH] Added saturate script function (+documentation), it also desaturates git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@800 0fc631ac-6414-0410-93d0-97cfa31319b6 --- doc/function/image5.png | Bin 0 -> 10468 bytes doc/function/image_saturate1.png | Bin 0 -> 10462 bytes doc/function/image_saturate2.png | Bin 0 -> 10401 bytes doc/function/index.txt | 3 +- doc/function/saturate.txt | 21 ++++++++++++ src/gfx/generated_image.cpp | 21 ++++++++---- src/gfx/generated_image.hpp | 50 ++++++++++++++++++++-------- src/gfx/gfx.hpp | 7 ++-- src/gfx/image_effects.cpp | 55 +++++++++++++++++-------------- src/gui/packages_window.cpp | 4 +-- src/script/functions/image.cpp | 7 ++++ 11 files changed, 114 insertions(+), 54 deletions(-) create mode 100644 doc/function/image5.png create mode 100644 doc/function/image_saturate1.png create mode 100644 doc/function/image_saturate2.png create mode 100644 doc/function/saturate.txt diff --git a/doc/function/image5.png b/doc/function/image5.png new file mode 100644 index 0000000000000000000000000000000000000000..437a8f811c6a783cee4b409455214c41e17c2afe GIT binary patch literal 10468 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 U-&Cm+Z~y=R07*qoM6N<$g5eSiS^xk5 literal 0 HcmV?d00001 diff --git a/doc/function/image_saturate2.png b/doc/function/image_saturate2.png new file mode 100644 index 0000000000000000000000000000000000000000..0940a8aab1687d36fb67f561e07bdb76da8b8dc2 GIT binary patch literal 10401 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 saturate(input: image, amount: saturation amount) + +Saturate or desaturate an image. Saturation makes the colors brighter, desaturation makes the image more grey. + +To saturate use an amount between @0@ (no saturation) and @1@ (super crazy, too much saturation). + +To desaturate use an amount between @0@ (no desaturation) and @-1@ (convert to greyscale). + +--Parameters-- +! Parameter Type Description +| @input@ [[type:image]] Image to (de)saturate. +| @alpha@ [[type:double]] Saturation factor. + +--Examples-- +> saturate("image5.png", amount: 0.5) == [[Image]] +>>> saturate("image5.png", amount: 0.5) == "image_saturate1.png" +> saturate("image5.png", amount: -0.5) == [[Image]] +>>> saturate("image5.png", amount: -0.5) == "image_saturate2.png" diff --git a/src/gfx/generated_image.cpp b/src/gfx/generated_image.cpp index f8253798..4d5fbe03 100644 --- a/src/gfx/generated_image.cpp +++ b/src/gfx/generated_image.cpp @@ -74,7 +74,7 @@ Image conform_image(const Image& img, const GeneratedImage::Options& options) { } // saturate? if (options.saturate) { - saturate(image, 40); + saturate(image, .1); } options.width = image.GetWidth(); options.height = image.GetHeight(); @@ -159,9 +159,6 @@ Image SetMaskImage::generate(const Options& opt) const { set_alpha(img, mask->generate(opt)); return img; } -ImageCombine SetMaskImage::combine() const { - return image->combine(); -} bool SetMaskImage::operator == (const GeneratedImage& that) const { const SetMaskImage* that2 = dynamic_cast(&that); return that2 && *image == *that2->image @@ -173,9 +170,6 @@ Image SetAlphaImage::generate(const Options& opt) const { set_alpha(img, alpha); return img; } -ImageCombine SetAlphaImage::combine() const { - return image->combine(); -} bool SetAlphaImage::operator == (const GeneratedImage& that) const { const SetAlphaImage* that2 = dynamic_cast(&that); return that2 && *image == *that2->image @@ -196,6 +190,19 @@ bool SetCombineImage::operator == (const GeneratedImage& that) const { && image_combine == that2->image_combine; } +// ----------------------------------------------------------------------------- : SaturateImage + +Image SaturateImage::generate(const Options& opt) const { + Image img = image->generate(opt); + saturate(img, amount); + return img; +} +bool SaturateImage::operator == (const GeneratedImage& that) const { + const SaturateImage* that2 = dynamic_cast(&that); + return that2 && *image == *that2->image + && amount == that2->amount; +} + // ----------------------------------------------------------------------------- : EnlargeImage Image EnlargeImage::generate(const Options& opt) const { diff --git a/src/gfx/generated_image.hpp b/src/gfx/generated_image.hpp index 3696d60d..8089a137 100644 --- a/src/gfx/generated_image.hpp +++ b/src/gfx/generated_image.hpp @@ -66,6 +66,20 @@ class GeneratedImage : public ScriptValue { /// Resize an image to conform to the options Image conform_image(const Image&, const GeneratedImage::Options&); +// ----------------------------------------------------------------------------- : SimpleFilterImage + +/// Apply some filter to a single image +class SimpleFilterImage : public GeneratedImage { + public: + inline SimpleFilterImage(const GeneratedImageP& image) + : image(image) + {} + virtual ImageCombine combine() const { return image->combine(); } + virtual bool local() const { return image->local(); } + protected: + GeneratedImageP image; +}; + // ----------------------------------------------------------------------------- : BlankImage /// An image generator that returns a blank image @@ -133,49 +147,57 @@ class CombineBlendImage : public GeneratedImage { // ----------------------------------------------------------------------------- : SetMaskImage /// Change the alpha channel of an image -class SetMaskImage : public GeneratedImage { +class SetMaskImage : public SimpleFilterImage { public: inline SetMaskImage(const GeneratedImageP& image, const GeneratedImageP& mask) - : image(image), mask(mask) + : SimpleFilterImage(image), mask(mask) {} virtual Image generate(const Options& opt) const; - virtual ImageCombine combine() const; virtual bool operator == (const GeneratedImage& that) const; - virtual bool local() const { return image->local() && mask->local(); } private: - GeneratedImageP image, mask; + GeneratedImageP mask; }; /// Change the alpha channel of an image -class SetAlphaImage : public GeneratedImage { +class SetAlphaImage : public SimpleFilterImage { public: inline SetAlphaImage(const GeneratedImageP& image, double alpha) - : image(image), alpha(alpha) + : SimpleFilterImage(image), alpha(alpha) {} virtual Image generate(const Options& opt) const; - virtual ImageCombine combine() const; virtual bool operator == (const GeneratedImage& that) const; - virtual bool local() const { return image->local(); } private: - GeneratedImageP image; double alpha; }; // ----------------------------------------------------------------------------- : SetCombineImage /// Change the combine mode -class SetCombineImage : public GeneratedImage { +class SetCombineImage : public SimpleFilterImage { public: inline SetCombineImage(const GeneratedImageP& image, ImageCombine image_combine) - : image(image), image_combine(image_combine) + : SimpleFilterImage(image), image_combine(image_combine) {} virtual Image generate(const Options& opt) const; virtual ImageCombine combine() const; virtual bool operator == (const GeneratedImage& that) const; - virtual bool local() const { return image->local(); } + private: + ImageCombine image_combine; +}; + +// ----------------------------------------------------------------------------- : SaturateImage + +/// Saturate/desaturate an image +class SaturateImage : public SimpleFilterImage { + public: + inline SaturateImage(const GeneratedImageP& image, double alpha) + : SimpleFilterImage(image), amount(amount) + {} + virtual Image generate(const Options& opt) const; + virtual bool operator == (const GeneratedImage& that) const; private: GeneratedImageP image; - ImageCombine image_combine; + double amount; }; // ----------------------------------------------------------------------------- : EnlargeImage diff --git a/src/gfx/gfx.hpp b/src/gfx/gfx.hpp index d74a4d6d..86693859 100644 --- a/src/gfx/gfx.hpp +++ b/src/gfx/gfx.hpp @@ -92,11 +92,8 @@ void mask_blend(Image& img1, const Image& img2, const Image& mask); // ----------------------------------------------------------------------------- : Effects -/// Saturate an image, amount should be in range [0...100] -void saturate(Image& image, int amount); - -/// Desaturate an image -void desaturate(Image& image); +/// Saturate an image +void saturate(Image& image, double amount); // ----------------------------------------------------------------------------- : Combining diff --git a/src/gfx/image_effects.cpp b/src/gfx/image_effects.cpp index 1e3190ab..be7a2255 100644 --- a/src/gfx/image_effects.cpp +++ b/src/gfx/image_effects.cpp @@ -12,33 +12,38 @@ // ----------------------------------------------------------------------------- : Saturation -void saturate(Image& image, int amount) { +void saturate(Image& image, double amount) { if (amount == 0) return; // nothing to do - int factor = 300 / amount; - int div = factor - 2; - // for each pixel... Byte* pix = image.GetData(); Byte* end = pix + image.GetWidth() * image.GetHeight() * 3; - while (pix != end) { - int r = pix[0], g = pix[1], b = pix[2]; - int r2 = (factor * r - g - b) / div; - int g2 = (factor * g - r - b) / div; - int b2 = (factor * b - r - g) / div; - pix[0] = col(r2); - pix[1] = col(g2); - pix[2] = col(b2); - pix += 3; - } -} - -void desaturate(Image& image/*, int amount*/) { - Byte* pix = image.GetData(); - Byte* end = pix + image.GetWidth() * image.GetHeight() * 3; - while (pix != end) { - int r = pix[0], g = pix[1], b = pix[2]; - pix[0] = (r+r+g+b) / 4; - pix[1] = (g+r+g+b) / 4; - pix[2] = (b+r+g+b) / 4; - pix += 3; + if (amount > 0) { + amount = min(amount,0.99); + int factor = 256 * amount; + int div = 768 - 3 * factor; + while (pix != end) { + int r = pix[0], g = pix[1], b = pix[2]; + int avg = factor*(r+g+b); + pix[0] = col((768*r - avg) / div); + pix[1] = col((768*g - avg) / div); + pix[2] = col((768*b - avg) / div); + pix += 3; + } + } else if (amount < -0.99) { + while (pix != end) { + int r = pix[0], g = pix[1], b = pix[2]; + pix[0] = pix[1] = pix[2] = (r+g+b)/3; + pix += 3; + } + } else { + int factor1 = 256 * -amount; + int factor2 = 768 - 3*factor1; + while (pix != end) { + int r = pix[0], g = pix[1], b = pix[2]; + int avg = factor1*(r+g+b); + pix[0] = (factor2*r + avg) / 768; + pix[1] = (factor2*g + avg) / 768; + pix[2] = (factor2*b + avg) / 768; + pix += 3; + } } } diff --git a/src/gui/packages_window.cpp b/src/gui/packages_window.cpp index 68a943c9..2e9d5275 100644 --- a/src/gui/packages_window.cpp +++ b/src/gui/packages_window.cpp @@ -277,7 +277,7 @@ class PackageIconRequest : public ThumbnailRequest { Image resampled(16,16,false); resample_preserve_aspect(image,resampled); ti->icon = Bitmap(resampled); - desaturate(resampled); + saturate(resampled, -.75); set_alpha(resampled,0.5); ti->icon_grey = Bitmap(resampled); list->Refresh(false); @@ -318,7 +318,7 @@ void PackageUpdateList::initItems() { image = load_resource_image(_("installer_group")); } ti.icon = Bitmap(image); - desaturate(image); + saturate(image, -.75); set_alpha(image, 0.5); ti.icon_grey = Bitmap(image); if (p && !p->description->icon.Ok() && !p->description->icon_url.empty()) { diff --git a/src/script/functions/image.cpp b/src/script/functions/image.cpp index f29bf60d..161b5029 100644 --- a/src/script/functions/image.cpp +++ b/src/script/functions/image.cpp @@ -79,6 +79,12 @@ SCRIPT_FUNCTION(set_combine) { return new_intrusive2(input, image_combine); } +SCRIPT_FUNCTION(saturate) { + SCRIPT_PARAM_C(GeneratedImageP, input); + SCRIPT_PARAM(double, amount); + return new_intrusive2(input, amount); +} + SCRIPT_FUNCTION(enlarge) { SCRIPT_PARAM_C(GeneratedImageP, input); SCRIPT_PARAM_N(double, _("border size"), border_size); @@ -170,6 +176,7 @@ void init_script_image_functions(Context& ctx) { ctx.setVariable(_("set mask"), script_set_mask); ctx.setVariable(_("set alpha"), script_set_alpha); ctx.setVariable(_("set combine"), script_set_combine); + ctx.setVariable(_("saturate"), script_saturate); ctx.setVariable(_("enlarge"), script_enlarge); ctx.setVariable(_("crop"), script_crop); ctx.setVariable(_("drop shadow"), script_drop_shadow);