pleabo

Kaleidoscope Effect Plugin

26 posts in this topic

From a newbie, this is a port of some HLSL FX code that I wrote for a Kaleidoscope Effect for Windows Movie Maker 6.0; I just wanted to see how the Paint.Net coding tool Code Lab works and to get some experience with Paint.net and the C# language.

It is a similar, but a bit different than the Kaleidoscope Effect that Madjik submitted around 2008. This one adds a center point selector and a source angle rotater. The pie shaped selection is just the image swept out by rotating clockwise 360/n degrees. It is missing Madjik's copy all over all option, show single piece etc.

Also the edge of the image can be clamped or repeated.

Anyway, just for fun. Here is the DLL DPL KAL.zip (Edit: Upload by EER 16 April 2017)

Unzip and place the DLL in the .../Paint.Net/Effects folder.

Then DPL Kaleidoscope will show up in the Effect->Distort menu

Here is a sample with a elliptical selection followed by a rectangular selection.

kalsampled.png

Also of course the whole canvas can be selected (by selecting nothing).

kaldj.jpg

The UI is:

KaleidoscopeUI.png

The controls are:

  • The Selection Rectangle = Drawing Destination
    (Lasso, Ellipse and Inverted Selections gives some interesting results)
  • (Source Center) Selector - x y position of the center to be processed
  • (Source Angle) Chooser - Rotate the start of the pie to be copied
  • (Destination Angle) Chooser - Rotate the resulting kaleidoscope image
  • (Zoom) Slider - Zoom in/out on the kaleidoscope image
  • (Repetitions) Slider - Number of copies
  • (Imaging Type) Radio Buttons
    Reflect, Left, Right
  • (Clamp Edge / Repeat) At Edge Check Box -
  • (Ellipse / Rectangle) Check Box - clip at a rectangle or ellipse representing the selection area
  • (Border Width) Slider (0 for none) -
  • (Colored Background) Checkbox - Surround the selection with a single color
  • (Background Color) Color Wheel - Choose border color and surrounding color when colored background is on.
  • (Distort) CheckBox - Gives a bit of a spherical look. Originally a bug, now featured boltbait.roll.png.

Edit: Per Rick suggestion, changed the Image Type radio buttons to a dropdown list. UI is now 780 pixels tall.

Also, a later post has a 750 pixel version with the Distort checkbox removed.

Comments welcome, pleabo

Edited by Ego Eram Reputo
Added UI image and zipped *.DLL
1

Share this post


Link to post
Share on other sites

I know I`m no plug in maker myself so I wouldn't have a clue how to do it myself but how about using a tabbed interface? I`ve seen it used on other plug ins.

0

Share this post


Link to post
Share on other sites

CSM725 and Goonfella. Till I figure out how to rearrange the UI, here is one with the Color Chooser removed.

It has a UI about 700 pixels tall. The background/border color is hard coded to dark blue. DPLKALsmall.zip

Following is one 690 pixel candidate for what I would like to do: (Click for full size)

ui3.th.png

But so far I don't know how to arrange radio buttons or check boxes horizontally.??

Edited by pleabo
0

Share this post


Link to post
Share on other sites

You can't stack controls horizontally like that in CodeLab. CodeLab uses a UI system called IndirectUI that Rick wrote to simplify UI design. Although IndirectUI makes UI design easier, it also imposes some limits on control placement. If you want to move the controls around at will, you would have to switch over to an IDE, such as Visual Studio or SharpDevelop, and learn to use WinForms.

0

Share this post


Link to post
Share on other sites

You can, however, tell the StaticListChoiceProperty to use a dropdown list (combobox) instead of a vertical list of radio buttons. That will save some space.

0

Share this post


Link to post
Share on other sites

With Rick's suggestion of combobox for Image Type and removing the Distort check box, here is a 750 pixel tall UI version.

kals2.th.png(Click image for full size)

DPLKALsmall2.zip Save the DLL to the Effects folder.

Any comments about function?

Edited by pleabo
0

Share this post


Link to post
Share on other sites

This plugin is done. If a moderator chooses, this thread can be moved to Plugins - Publishing Only.

PatrickL

0

Share this post


Link to post
Share on other sites

This plugin is done. If a moderator chooses, this thread can be moved to Plugins - Publishing Only.

Done. Feel free to rename the thread, perhaps to remove "Newbie". It's up to you though.

0

Share this post


Link to post
Share on other sites

Downloaded ! This looks wonderful from the sample images you have provided. Can't wait to give it a try.

0

Share this post


Link to post
Share on other sites

lovely plugin. I've downloaded and started a few play items. Look forward to pushing this plugin to the limit in art.

ciao

thanks for sharing your plugin with us.

OMA

0

Share this post


Link to post
Share on other sites

Thanks Possum and Oma.

I've seen both or your artwork, and since I'm artistically challenged I'll be looking forward to seeing what you all can do with this idea.

PatrickL

0

Share this post


Link to post
Share on other sites

This gives some interesting results, but it is difficult to predict how it will look like. The repeted piece isn't clearly identified.

Anyhow I would be interested to have a look at the source...

0

Share this post


Link to post
Share on other sites

This gives some interesting results, but it is difficult to predict how it will look like. The repeted piece isn't clearly identified.

Anyhow I would be interested to have a look at the source...

Thanks for your interest. OK, here's the code:

#region UICode
Pair<double, double> Amount1 = Pair.Create( 0.0 , 0.0 ); // Source Center
double Amount2 = 0; // [-180,180] Source Angle
double Amount3 = 0; // [-180,180] Destination Angle
double Amount4 = 1; // [0.1,10] Zoom
int Amount5 = 4; // [1,50] Repetitions
byte Amount6 = 0; // Imaging Type|Reflect| Left| Right
bool Amount7 = false; // [0,1] Clamp Edge
bool Amount8 = true; // [0,1] Ellipse
int Amount9 = 0; // [0,512] Border Width (0 for none)
bool Amount10 = false; // [0,1] Colored Ellipse Background
ColorBgra Amount11 = ColorBgra.FromBgr(0,0,0); // Border/BackGround Color
bool Amount12 = false; // [0,1] Distort
#endregion

// Submenu: Distort
// Name: DPL Kaleidoscope
// Title: DPL Kaleidoscope
// Author: pleabo

void Render(Surface dst, Surface src, Rectangle rect) {
 Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
 int xx, yy;
 double PI = Math.PI;
 ColorBgra CurrentPixel;
 double ctrX    = Amount1.First;  // Source Center x
 double ctrY    = Amount1.Second; // Source Center y
 double angleS   = Amount2/180*PI; // [-180,180] Source Angle
 double angleD   = Amount3/180*PI; // [-180,180] Destination Angle
 double zoom 	= Amount4;  // [1,10] Zoom X
 int    nn   	= Amount5;  // [1,50] Number of Reflections
 byte   itype    = Amount6;  // Reflect| Left| Right
 bool   clmp 	= Amount7;  // [0,1] Clamp Edge
 bool   iselip   = Amount8;  // Do Elipse
 int    bdr      = Amount9;  // Border Thickness
 bool   bgclr    = Amount10; // [0,1] Do Background Color
 ColorBgra clrbg = Amount11; // The Background Color
 bool   distort  = Amount12; // Distort the Destination  

 int    width  = src.Width; 	// Source - Whole Image
 int    height = src.Height;

 int right  = rect.Right;   	// Selection (Partial Destination)
 int left   = rect.Left;
 int top    = rect.Top;
 int bottom = rect.Bottom;

 int dright  = selection.Right; // Selection (Whole Destination)
 int dleft   = selection.Left;
 int dtop    = selection.Top;  
 int dbottom = selection.Bottom;
 int dwidth  = dright - dleft;
 int dheight = dbottom - dtop;  

 double magx   = (double)width /dwidth;
 double magy   = (double)height/dheight;
 double magxy  = Math.Min(magx, magy);  // Pick smallest side

 int    scx    = (int)(ctrX*width /2+ width/2 ); // Source Center XY
 int    scy    = (int)(ctrY*height/2+ height/2); 
 int    dcx    = (int)((dwidth)/2+dleft);  // Destination Center XY
 int    dcy    = (int)((dheight)/2+dtop);

 if (itype==0) nn *= 2;   // Make visual number of nodes match nn in reflect mode
 if (distort)  nn *= 2;   // Keep number of nodes when distorting  
 if (bgclr) bdr=0;        // No border if colored background
 for (int y = top; y < bottom; y++) {
   for (int x = left; x < right; x++) {
     CurrentPixel = src[x,y];        
     if (IsIn(x,y,dleft, dtop, dright-dleft, dbottom-dtop, iselip)) {
       CurrentPixel = clrbg;        // Border color
       int rmin = Math.Min(dright-dleft, dbottom-dtop)/2;        
       if (bdr<rmin) {   // Keep center at clrbg for big border 
         if (IsIn(x,y,dleft+bdr, dtop+bdr, dright-dleft-2*bdr, dbottom-dtop-2*bdr, iselip)) {
           int dx = x-dcx;
           int dy = y-dcy;
           double dist = distort ? 0.5 : 1.0;      
           double angle = dist*nn*(Math.Atan2(dy,-dx)+PI-angleD);
           int n = (int)(((angle+(2*nn-1)*PI)/(PI/nn*2)+nn/2)/(nn))%(nn); // Section number - 0->(2*Reflections-1)

           double angleL = (angle-n*2*PI)/(1*nn); 			// As Is
           double angleR = 2*PI/(1*nn)-(angle-n*2*PI)/(1*nn); // Mirror

           switch (itype) {
             case 0: angle = ((n%2)>0)?angleL:angleR;break; // Alternate        
             case 1: angle = angleL; break; 				// Left
             case 2: angle = angleR; break; 				// Right
           }

           double sinxy = Math.Sin(angle-angleS);
           double cosxy = Math.Cos(angle-angleS);

           int sx = (int)(dx*magxy); 
           int sy = (int)(dy*magxy);      

           double sxy2 = sx*sx + sy*sy;  // Sum of squares
           double rS = Math.Sqrt(sxy2)/zoom*magxy; // Radius (distance to center)*Konstant

           xx = (int)(scx + rS*cosxy);  
           yy = (int)(scy + rS*sinxy);  
           if (clmp) {
             xx = Clamp(xx,width -1);                    
             yy = Clamp(yy,height-1);  
           }else{            
             xx = Repeat(xx,width );                    
             yy = Repeat(yy,height);  
           }
           CurrentPixel = src[Math.Abs(xx), Math.Abs(yy)];
         }
       }
     } else CurrentPixel = bgclr ? clrbg : src[x,y]; // BackGround/Original Pixel 		
     dst[x,y] = CurrentPixel;
   }
 }
}

// ----------------  Checking for x,y in rectangle or ellipse ------- x2/a2 + y2/b2 = 1 --
public bool IsIn(int x,int y,int rx, int ry, int rl, int rh, bool elips) {
bool rc = false;    
 if (elips) {
   int cx = rx+rl/2,   	cy = ry+rh/2;
   int dx = (x-cx)*(x-cx), dy = (y-cy)*(y-cy);
   float z2 = rl*rl,   	w2 = rh*rh;
   rc = (4*(dx/z2+dy/w2)<1);
 } else 
   rc = (x<rx)?false:(x>(rx+rl))?false:(y<ry)?false:(y>(ry+rh))?false:true;
 return rc;
}

// -------------- Clamp iValue to zero and upper ---------------
public int  Clamp(int iValue, int upper) {
return (int)Math.Max(Math.Min(iValue, upper), 0);
}

// --------------- Repeat iValue below zero and above upper (modulo upper)
public int Repeat(int iValue, int upper) {
 return iValue%upper;  
}

PatrickL

0

Share this post


Link to post
Share on other sites

Thanks !

You're code is clean and readable.

You could optimize it a bit if you move some unique calculation out of the loops (ex: int rmin=... doesn't depend on x nor y).

Your zoom out (ex: zoom = 0.4) is great and gives amazing results with repeat the effect (ctrl+F)

0

Share this post


Link to post
Share on other sites

My only complaint is how low the quality is compared to the other plugin. It honestly makes it not worth using. Is there a way of fixing that?

0

Share this post


Link to post
Share on other sites

It only seems to happen at higher-repetition levels, and zooming out fixes a little bit of it, but it's still an issue.

6ZJcK.png

0

Share this post


Link to post
Share on other sites
8 minutes ago, AndrewDavid said:

Links to plugins unavailable. Next step?

 

Build your own from the CodeLab source code listed above?

0

Share this post


Link to post
Share on other sites

Posted (edited)

Now that was a nice learning experience. So easy when you have the source code. Now if I could just understand what all the code meant - I might become a publisher. Thanks Boltbait for suggesting I try it. My first plug- in written by me (well sort of).

Edited by AndrewDavid
removed image - too large signature
0

Share this post


Link to post
Share on other sites

^ Glad you pulled it off AndrewDavid ;)

 

For anyone not interested in compiling the source, I've added a zipped DLL to the first post and also added an image of the UI.

1

Share this post


Link to post
Share on other sites

<3 Dear Maximilian! Thank you for these wonderful plugins. I have the latest version. Perfect for the 3.5.11 users. :cake: :coffee:

1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now