mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
New image functions:
* invert * flip_horizontal * flip_vertical * rotate git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1472 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
Function: flip_horizontal
|
||||
|
||||
--Usage--
|
||||
> flip_horizontal(input: image)
|
||||
|
||||
Flip an image horizontally.
|
||||
|
||||
--Parameters--
|
||||
! Parameter Type Description
|
||||
| @input@ [[type:image]] Image to flip.
|
||||
|
||||
--Examples--
|
||||
> flip_horizontal("image_logo.png") == [[Image]]
|
||||
>>> flip_horizontal(<img src="image_logo.png" alt='"image_logo.png"' style="border:1px solid black;vertical-align:middle;margin:1px;" />) == <img src="image_logo_hflip.png" alt='"image_logo_hflip.png"' style="border:1px solid black;vertical-align:middle;margin:1px;" />
|
||||
|
||||
--See also--
|
||||
| [[fun:flip_vertical]] Flip an image vertically
|
||||
| [[fun:rotate]] Rotate an image
|
||||
@@ -0,0 +1,18 @@
|
||||
Function: flip_vertical
|
||||
|
||||
--Usage--
|
||||
> flip_vertical(input: image)
|
||||
|
||||
Flip an image vertically.
|
||||
|
||||
--Parameters--
|
||||
! Parameter Type Description
|
||||
| @input@ [[type:image]] Image to flip.
|
||||
|
||||
--Examples--
|
||||
> flip_vertical("image_logo.png") == [[Image]]
|
||||
>>> flip_vertical(<img src="image_logo.png" alt='"image_logo.png"' style="border:1px solid black;vertical-align:middle;margin:1px;" />) == <img src="image_logo_vflip.png" alt='"image_logo_vflip.png"' style="border:1px solid black;vertical-align:middle;margin:1px;" />
|
||||
|
||||
--See also--
|
||||
| [[fun:flip_horizontal]] Flip an image horizontally
|
||||
| [[fun:rotate]] Rotate an image
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
@@ -83,8 +83,12 @@ These functions are built into the program, other [[type:function]]s can be defi
|
||||
| [[fun:set_alpha]] Change the transparency of an image.
|
||||
| [[fun:set_combine]] Change how the image should be combined with the background.
|
||||
| [[fun:saturate]] Saturate/desaturate an image.
|
||||
| [[fun:invert]] Invert the colors of an image.
|
||||
| [[fun:enlarge]] Enlarge an image by putting a border around it.
|
||||
| [[fun:crop]] Crop an image, giving only a small subset of it.
|
||||
| [[fun:flip_horizontal]] Flip an image horizontally.
|
||||
| [[fun:flip_vertical]] Flip an image vertically.
|
||||
| [[fun:rotate]] Rotate an image.
|
||||
| [[fun:drop_shadow]] Add a drop shadow to an image.
|
||||
| [[fun:symbol_variation]] Render a variation of a [[type:symbol]].
|
||||
| [[fun:built_in_image]] Return an image built into the program.
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
Function: invert
|
||||
|
||||
--Usage--
|
||||
> invert(input: image)
|
||||
|
||||
Invert the colors in an image.
|
||||
|
||||
--Parameters--
|
||||
! Parameter Type Description
|
||||
| @input@ [[type:image]] Image to invert.
|
||||
|
||||
--Examples--
|
||||
> invert("image_logo.png") == [[Image]]
|
||||
>>> invert(<img src="image_logo.png" alt='"image_logo.png"' style="border:1px solid black;vertical-align:middle;margin:1px;" />) == <img src="image_logo_invert.png" alt='"image_logo_invert.png"' style="border:1px solid black;vertical-align:middle;margin:1px;" />
|
||||
@@ -0,0 +1,19 @@
|
||||
Function: flip_vertical
|
||||
|
||||
--Usage--
|
||||
> rotate(input: image, angle: some_number)
|
||||
|
||||
Rotate an image. The image can become larger to accomodate the rotated bounding box.
|
||||
|
||||
--Parameters--
|
||||
! Parameter Type Description
|
||||
| @input@ [[type:image]] Image to rotate.
|
||||
| @angle@ [[type:double]] Angle to rotate by, in degrees counter clockwise.
|
||||
|
||||
--Examples--
|
||||
> rotate("image_logo.png", angle:30) == [[Image]]
|
||||
>>> rotate(<img src="image_logo.png" alt='"image_logo.png"' style="border:1px solid black;vertical-align:middle;margin:1px;" />, angle:30) == <img src="image_logo_rotate30.png" alt='"image_logo_rotate30.png"' style="border:1px solid black;vertical-align:middle;margin:1px;" />
|
||||
|
||||
--See also--
|
||||
| [[fun:flip_horizontal]] Flip an image horizontally
|
||||
| [[fun:flip_vertical]] Flip an image vertically
|
||||
@@ -19,3 +19,5 @@ To desaturate use an amount between @0@ (no desaturation) and @-1@ (convert to g
|
||||
>>> saturate(<img src="image5.png" alt='"image5.png"' style="border:1px solid black;vertical-align:middle;margin:1px;" />, amount: 0.5) == <img src="image_saturate1.png" alt='"image_saturate1.png"' style="border:1px solid black;vertical-align:middle;margin:1px;" />
|
||||
> saturate("image5.png", amount: -0.5) == [[Image]]
|
||||
>>> saturate(<img src="image5.png" alt='"image5.png"' style="border:1px solid black;vertical-align:middle;margin:1px;" />, amount: -0.5) == <img src="image_saturate2.png" alt='"image_saturate2.png"' style="border:1px solid black;vertical-align:middle;margin:1px;" />
|
||||
> saturate("image_logo.png", amount: -1) == [[Image]]
|
||||
>>> saturate(<img src="image_logo.png" alt='"image_logo.png"' style="border:1px solid black;vertical-align:middle;margin:1px;" />, amount: -1) == <img src="image_logo_desaturate.png" alt='"image_logo_desaturate.png"' style="border:1px solid black;vertical-align:middle;margin:1px;" />
|
||||
|
||||
@@ -41,8 +41,13 @@ IMPLEMENT_REFLECTION(ColorField) {
|
||||
// ----------------------------------------------------------------------------- : ColorField::Choice
|
||||
|
||||
IMPLEMENT_REFLECTION(ColorField::Choice) {
|
||||
REFLECT(name);
|
||||
REFLECT(color);
|
||||
if (tag.reading() && !tag.isComplex()) {
|
||||
REFLECT_NAMELESS(name);
|
||||
color = parse_color(name);
|
||||
} else {
|
||||
REFLECT(name);
|
||||
REFLECT(color);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : ColorStyle
|
||||
|
||||
@@ -60,9 +60,31 @@ Color hsl2rgb(double h, double s, double l);
|
||||
/// A darker version of a color
|
||||
Color darken(const Color& c);
|
||||
|
||||
/// A black or white color, that contrasts with c
|
||||
Color contrasting_color(const Color& c);
|
||||
|
||||
/// A saturated version of a color
|
||||
Color saturate(const Color& c, double amount);
|
||||
|
||||
/// Recolor:
|
||||
/**
|
||||
* Maps
|
||||
* black -> black
|
||||
* red -> cr
|
||||
* green -> cg
|
||||
* blue -> cb
|
||||
* white -> cw
|
||||
*
|
||||
* Allows for interpolation between the colors, so for example
|
||||
* rgb(128,128,128) -> 0.5*cw
|
||||
* rgb(128,128,0) -> 0.5*cr + 0.5*cg
|
||||
* rgb(128,0,0) -> 0.5*cr
|
||||
*/
|
||||
Color recolor(Color const& c, Color const& cr, Color const& cg, Color const& cb, Color const& cw);
|
||||
Image recolor(Image const& im, Color const& cr, Color const& cg, Color const& cb, Color const& cw);
|
||||
/// Like recolor: map green to similar black/white and blue to complementary white/black
|
||||
Image recolor(Image const& im, Color const& cr);
|
||||
|
||||
/// Fills an image with the specified color
|
||||
void fill_image(Image& image, const Color& color);
|
||||
|
||||
|
||||
@@ -196,6 +196,48 @@ bool SaturateImage::operator == (const GeneratedImage& that) const {
|
||||
&& amount == that2->amount;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : InvertImage
|
||||
|
||||
Image InvertImage::generate(const Options& opt) const {
|
||||
Image img = image->generate(opt);
|
||||
invert(img);
|
||||
return img;
|
||||
}
|
||||
bool InvertImage::operator == (const GeneratedImage& that) const {
|
||||
const InvertImage* that2 = dynamic_cast<const InvertImage*>(&that);
|
||||
return that2 && *image == *that2->image;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : FlipImage
|
||||
|
||||
Image FlipImageHorizontal::generate(const Options& opt) const {
|
||||
Image img = image->generate(opt);
|
||||
return flip_image_horizontal(img);
|
||||
}
|
||||
bool FlipImageHorizontal::operator == (const GeneratedImage& that) const {
|
||||
const FlipImageHorizontal* that2 = dynamic_cast<const FlipImageHorizontal*>(&that);
|
||||
return that2 && *image == *that2->image;
|
||||
}
|
||||
|
||||
Image FlipImageVertical::generate(const Options& opt) const {
|
||||
Image img = image->generate(opt);
|
||||
return flip_image_vertical(img);
|
||||
}
|
||||
bool FlipImageVertical::operator == (const GeneratedImage& that) const {
|
||||
const FlipImageVertical* that2 = dynamic_cast<const FlipImageVertical*>(&that);
|
||||
return that2 && *image == *that2->image;
|
||||
}
|
||||
|
||||
Image RotateImage::generate(const Options& opt) const {
|
||||
Image img = image->generate(opt);
|
||||
return rotate_image(img,angle);
|
||||
}
|
||||
bool RotateImage::operator == (const GeneratedImage& that) const {
|
||||
const RotateImage* that2 = dynamic_cast<const RotateImage*>(&that);
|
||||
return that2 && *image == *that2->image
|
||||
&& angle == that2->angle;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : EnlargeImage
|
||||
|
||||
Image EnlargeImage::generate(const Options& opt) const {
|
||||
|
||||
@@ -202,6 +202,52 @@ class SaturateImage : public SimpleFilterImage {
|
||||
double amount;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : InvertImage
|
||||
|
||||
/// Invert an image
|
||||
class InvertImage : public SimpleFilterImage {
|
||||
public:
|
||||
inline InvertImage(const GeneratedImageP& image)
|
||||
: SimpleFilterImage(image)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : FlipImage
|
||||
|
||||
/// Flip an image horizontally
|
||||
class FlipImageHorizontal : public SimpleFilterImage {
|
||||
public:
|
||||
inline FlipImageHorizontal(const GeneratedImageP& image)
|
||||
: SimpleFilterImage(image)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
};
|
||||
|
||||
/// Flip an image vertically
|
||||
class FlipImageVertical : public SimpleFilterImage {
|
||||
public:
|
||||
inline FlipImageVertical(const GeneratedImageP& image)
|
||||
: SimpleFilterImage(image)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
};
|
||||
|
||||
/// Rotate an image
|
||||
class RotateImage : public SimpleFilterImage {
|
||||
public:
|
||||
inline RotateImage(const GeneratedImageP& image, double angle)
|
||||
: SimpleFilterImage(image), angle(angle)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
private:
|
||||
double angle;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : EnlargeImage
|
||||
|
||||
/// Enlarge an image by adding a border around it
|
||||
|
||||
+9
-2
@@ -74,8 +74,12 @@ inline double rad_to_deg(double rad) { return rad * (180.0 / M_PI); }
|
||||
inline double deg_to_rad(double deg) { return deg * (M_PI / 180.0); }
|
||||
|
||||
/// Rotates an image counter clockwise
|
||||
/// angle must be a multiple of 90, i.e. {0,90,180,270}
|
||||
Image rotate_image(const Image& image, int angle);
|
||||
Image rotate_image(const Image& image, double angle);
|
||||
|
||||
/// Flip an image horizontally
|
||||
Image flip_image_horizontal(const Image& image);
|
||||
/// Flip an image vertically
|
||||
Image flip_image_vertical(const Image& image);
|
||||
|
||||
// ----------------------------------------------------------------------------- : Blending
|
||||
|
||||
@@ -98,6 +102,9 @@ void mask_blend(Image& img1, const Image& img2, const Image& mask);
|
||||
/// Saturate an image
|
||||
void saturate(Image& image, double amount);
|
||||
|
||||
/// Invert the colors in an image
|
||||
void invert(Image& img);
|
||||
|
||||
// ----------------------------------------------------------------------------- : Combining
|
||||
|
||||
/// Ways in which images can be combined, similair to what Photoshop supports
|
||||
|
||||
@@ -60,3 +60,13 @@ void saturate(Image& image, double amount) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Color inversion
|
||||
|
||||
void invert(Image& img) {
|
||||
Byte* data = img.GetData();
|
||||
int n = 3 * img.GetWidth() * img.GetHeight();
|
||||
for (int i = 0 ; i < n ; ++i) {
|
||||
data[i] = 255 - data[i];
|
||||
}
|
||||
}
|
||||
|
||||
+50
-16
@@ -83,24 +83,58 @@ struct Rotate270 {
|
||||
|
||||
// ----------------------------------------------------------------------------- : Interface
|
||||
|
||||
Image rotate_image(const Image& image, int angle) {
|
||||
switch (angle % 360) {
|
||||
case 0: return image;
|
||||
case 90: return rotate_image_impl<Rotate90> (image);
|
||||
case 180: return rotate_image_impl<Rotate180>(image);
|
||||
case 270: return rotate_image_impl<Rotate270>(image);
|
||||
default:
|
||||
if (!image.HasAlpha()) const_cast<Image&>(image).InitAlpha();
|
||||
return image.Rotate(angle * M_PI / 180, wxPoint(0,0));
|
||||
double almost_equal(double x, double y) {
|
||||
return fabs(x-y) < 1e-6;
|
||||
}
|
||||
|
||||
Image rotate_image(const Image& image, double angle) {
|
||||
double a = fmod(angle, 360);
|
||||
if (almost_equal(a, 0)) return image;
|
||||
if (almost_equal(a, 90)) return rotate_image_impl<Rotate90> (image);
|
||||
if (almost_equal(a,180)) return rotate_image_impl<Rotate180>(image);
|
||||
if (almost_equal(a,270)) return rotate_image_impl<Rotate270>(image);
|
||||
else {
|
||||
if (!image.HasAlpha()) const_cast<Image&>(image).InitAlpha();
|
||||
return image.Rotate(angle * M_PI / 180, wxPoint(0,0));
|
||||
}
|
||||
}
|
||||
|
||||
/*Bitmap rotate_bitmap(const Bitmap& bitmap, int angle) {
|
||||
switch (angle % 360) {
|
||||
case 90:
|
||||
case 180:
|
||||
case 270:
|
||||
default: return bitmap;
|
||||
|
||||
// ----------------------------------------------------------------------------- : Flipping images
|
||||
|
||||
// reverse a list of n chunks of size 'step'
|
||||
void do_flip(Byte const* in, Byte* out, int step, int n) {
|
||||
for (int i = 0, j = n-1 ; i < n ; ++i, --j) {
|
||||
memcpy(&out[i*step], &in[j*step], step);
|
||||
}
|
||||
}
|
||||
*/
|
||||
void do_flip(Byte const* in, Byte* out, int step1, int n1, int n2) {
|
||||
int step2 = step1 * n1;
|
||||
for (int i = 0 ; i < n2 ; ++i) {
|
||||
do_flip(in,out,step1,n1);
|
||||
in += step2;
|
||||
out += step2;
|
||||
}
|
||||
}
|
||||
|
||||
Image flip_image_horizontal(Image const& img) {
|
||||
int w = img.GetWidth(), h= img.GetHeight();
|
||||
Image out(w,h,false);
|
||||
do_flip(img.GetData(), out.GetData(), 3, w, h);
|
||||
if (img.HasAlpha()) {
|
||||
out.InitAlpha();
|
||||
do_flip(img.GetAlpha(), out.GetAlpha(), 1, w, h);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Image flip_image_vertical(Image const& img) {
|
||||
int w = img.GetWidth(), h= img.GetHeight();
|
||||
Image out(w,h,false);
|
||||
do_flip(img.GetData(), out.GetData(), 3 * w, h);
|
||||
if (img.HasAlpha()) {
|
||||
out.InitAlpha();
|
||||
do_flip(img.GetAlpha(), out.GetAlpha(), 1 * w, h);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -86,6 +86,11 @@ SCRIPT_FUNCTION(saturate) {
|
||||
return intrusive(new SaturateImage(input, amount));
|
||||
}
|
||||
|
||||
SCRIPT_FUNCTION(invert_image) {
|
||||
SCRIPT_PARAM_C(GeneratedImageP, input);
|
||||
return intrusive(new InvertImage(input));
|
||||
}
|
||||
|
||||
SCRIPT_FUNCTION(enlarge) {
|
||||
SCRIPT_PARAM_C(GeneratedImageP, input);
|
||||
SCRIPT_PARAM_N(double, _("border size"), border_size);
|
||||
@@ -101,6 +106,22 @@ SCRIPT_FUNCTION(crop) {
|
||||
return intrusive(new CropImage(input, width, height, offset_x, offset_y));
|
||||
}
|
||||
|
||||
SCRIPT_FUNCTION(flip_horizontal) {
|
||||
SCRIPT_PARAM_C(GeneratedImageP, input);
|
||||
return intrusive(new FlipImageHorizontal(input));
|
||||
}
|
||||
|
||||
SCRIPT_FUNCTION(flip_vertical) {
|
||||
SCRIPT_PARAM_C(GeneratedImageP, input);
|
||||
return intrusive(new FlipImageVertical(input));
|
||||
}
|
||||
|
||||
SCRIPT_FUNCTION(rotate) {
|
||||
SCRIPT_PARAM_C(GeneratedImageP, input);
|
||||
SCRIPT_PARAM_N(double, _("angle"), angle);
|
||||
return intrusive(new RotateImage(input,angle));
|
||||
}
|
||||
|
||||
SCRIPT_FUNCTION(drop_shadow) {
|
||||
SCRIPT_PARAM_C(GeneratedImageP, input);
|
||||
SCRIPT_OPTIONAL_PARAM_N_(double, _("offset x"), offset_x);
|
||||
@@ -190,8 +211,12 @@ void init_script_image_functions(Context& ctx) {
|
||||
ctx.setVariable(_("set alpha"), script_set_alpha);
|
||||
ctx.setVariable(_("set combine"), script_set_combine);
|
||||
ctx.setVariable(_("saturate"), script_saturate);
|
||||
ctx.setVariable(_("invert image"), script_invert_image);
|
||||
ctx.setVariable(_("enlarge"), script_enlarge);
|
||||
ctx.setVariable(_("crop"), script_crop);
|
||||
ctx.setVariable(_("flip horizontal"), script_flip_horizontal);
|
||||
ctx.setVariable(_("flip vertical"), script_flip_vertical);
|
||||
ctx.setVariable(_("rotate"), script_rotate);
|
||||
ctx.setVariable(_("drop shadow"), script_drop_shadow);
|
||||
ctx.setVariable(_("symbol variation"), script_symbol_variation);
|
||||
ctx.setVariable(_("built in image"), script_built_in_image);
|
||||
|
||||
Reference in New Issue
Block a user