Jump to content
How to Install Plugins ×

Tube Effect (ymd: 100718)


MadJik

Recommended Posts

Tube Effect

(or oblique cylinder?)

 

What's this?

Photo sample from:

http://www.photo-libre.fr

tube.jpg

 

This is a distort effect plugin. It allows you to distort the image as if you put in on a cylinder...

While moving, if the image leaves the area on a side it will reappear on the other.

 

In fact it was originally 99% made with CodeLab...(1% for external text editor, and for the icon).

 

 

Download the DLL

Plugin TubeOblique.dll

ar.pngHere is the DLLal.png

 

 

The MadJik's All plugins package is available !

http://forums.getpaint.net/index.php?showtopic=7186

 

 

How to install

Close Paint.net

 

Classic version of Paint.net

Unzip and (re)place the DLL in your Effect folder usually: C:/Program Files/Paint.NET/Effects

 

Microsoft Store version of Paint.net

Unzip and (re)place the DLL in your Effect folder usually: /My Documents/paint.net App Files/Effects/

You have to adapt for your language My Documents

 

 

The User interface

tube_UI.png

 

X,Y Offset (direction):

...you could choose the direction of the distortion.

Steps factor:

...you could increase the effect of distortion.

Quality:

...increasing the quality is slowering the rendering a bit, and should reduce the pixelisation.

Options:

_ Centered: if checked the borders are moving and the middle of the image is stable.

_ Horizontal flip: if checked the upper part moves in opposite way than the lower part, like a S or Z.

_ Vertical flip: if checked the right part moves in opposite way than the left part, like ~.

 

Examples:

 

tube_H.jpg  tube_V.jpg  tube_HV.jpg 

 

tube2.jpg

 

Tube3.jpg

 

Attention, need surounding but not everywhere!

Let's test with this simple image. Let's say the blue rectangle is the subject.

In this example the subject is in the middle of the area. The effect takes the full width of the selection and so the subject is moved down:

bad.png

 

For a better result (depending on what you are looking for!) you shoud cut/paste in a new image for the time to apply the effect.

Take away left/right margin and leave up/low transparent (for a vertical effect).

Then the effect is fully applied on the subject, most left and most right pixels don't move (or just 1-2 px).

good.png

 

Advanced Example

To make the 'glass' on the first picture:

I've set the background color to transparent.

I've resized the canvas only verticaly.

I mean the picture was (for example) 160x120 I enlarge the canvas to 160x300.

Be sure :

- there is no transparent border on left/right to have a nice tube effect.

- upper/lower borders are transparent...

Then I've duplicated the image.

And Applied Tube V:+0.60 steps 100 not centered, on the top layer

And Applied Tube V:-0.60 steps 100 not centered, on the second layer

And some other effects (shadow, glow, ..), I forgot to use the feather...

Please test it and give your comments...

Link to comment
Share on other sites

This looks really cool. Would you be able to add anti-aliasing?

 

Take responsibility for your own intelligence. 😉 -Rick Brewster

Link to comment
Share on other sites

Positioning of the object(you wish to tubulize) in the canvas is vital and can be very tricky.

Cool plugin but it needs some work. Anti-aliasing would be nice. Also, the panelling* of the object can be quite bothersome.


  • pdnpanellingti8.png*panelling


  • PDNmug.pngCoffee anyone?

BK_BloodSaw_sig.png

- DO NOT contact me asking for the .pdn of my avatar or the PDN logo. Thank you. Have a nice day.

Link to comment
Share on other sites

I'm still not sure why you're sampling the selectionRegion.IsVisible() at every pixel. The list of rectangles you get is limited to the selected region anyway, so this will always return true. I tried to tell BoltBait this about 5 times but it has still persisted in the template.

Also, instead of doing:

CurrentPixel = src[srcX,srcY];

try this:

CurrentPixel = src.GetBilinearSample(srcXd, srcYd);

And get rid of the IEEERemainder stuff. It will look much more better.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

"much more better"

So, you're saying it will look very good?

 

Take responsibility for your own intelligence. 😉 -Rick Brewster

Link to comment
Share on other sites

I'm still not sure why you're sampling the selectionRegion.IsVisible() at every pixel. The list of rectangles you get is limited to the selected region anyway, so this will always return true. I tried to tell BoltBait this about 5 times but it has still persisted in the template.

That is true... except for irregular selections.

If you don't check, you'll get issues like this:

SquareBug.png

Which I ran across when developing the Gradient plugin that I wrote.

Besides, you're the one that gave me the code in the first place. :D

Link to comment
Share on other sites

That is true... except for irregular selections.

No, it's completely true especially for irregular selections. The current selection is passed straight to the effect rendering harness. The whole point of the effect system in Paint.NET is that you don't have to worry about things like clipping to the selection, multicore scaling, etc.

If you don't check, you'll get issues like this:

SquareBug.png

Which I ran across when developing the Gradient plugin that I wrote.

I don't understand what you're showing me here. The layer thumbnail does not update while the effect is running. It sounds like an implementation problem, or you were using a beta version where things were operating differently.

Besides, you're the one that gave me the code in the first place. :D

No, I didn't give you that part of the code. I tried telling you several times that you don't need to call selectionRegion.IsVisible().

Edit: Woops, I did give you that code. But then I tried to correct myself in the very next post.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

@BuzzKill and All:

Ok for Antialias but how with Codelab?

Rick already told you... Use src.GetBilinearSample(srcXd, srcYd);

int Amount1=0;  //[-200,200]Horizontal cylinder factor 
int Amount2=0;  //[-200,200]Vertical cylinder factor 

void Render(Surface dst, Surface src, Rectangle rect) 
{ 
   PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds); 
   Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt(); 

   float RadiusY =(float)Amount1 / 100.0f; 
   float RadiusX =(float)Amount2 / 100.0f; 

   long SizeX = (long)(selection.Right - selection.Left); 
   long SizeY = (long)(selection.Bottom - selection.Top); 
   long CenterX = (long)((SizeX / 2.0f)+selection.Left); 
   long CenterY = (long)((SizeY / 2.0f)+selection.Top); 

   for(int y = rect.Top; y     { 
       for (int x = rect.Left; x         { 
           if (selectionRegion.IsVisible(x, y)) 
           { 
             float AngleY = (float)Math.Asin(2.0f*(float)(y - CenterY)/(float)SizeY); 
             float srcXd = (float)(Math.Cos(AngleY) * RadiusY * CenterY)+x; 
             if (srcXd               if (srcXd > SizeX) srcXd-=SizeX; 

             float AngleX = (float)Math.Acos(2.0f*(float)(x - CenterX)/(float)SizeX); 
             float srcYd = (float)(Math.Sin(AngleX) * RadiusX * CenterX)+y; 
             if (srcYd               if (srcYd > SizeY) srcYd-=SizeY;

             dst[x,y] = src.GetBilinearSample(srcXd, srcYd); 
          } 
       } 
   } 
}

Link to comment
Share on other sites

Much better! Thanks.

BK_BloodSaw_sig.png

- DO NOT contact me asking for the .pdn of my avatar or the PDN logo. Thank you. Have a nice day.

Link to comment
Share on other sites

Well, don't confuse antialiasing and sampling methods.

This may not make the edges smooth.

True, but I think barkbark00 was really asking for a better sampling method.

Now, if you leave some space around the image before you run the effect, the sampling method should create a sort of antialiasing. The only problem in this case is when the image repeats.

Link to comment
Share on other sites

Yeah I think you should be fine.

Rotate/Zoom does some weird faux-antialiasing so that the edges of the rectangle are smooth. I forget exactly how it does it; I wouldn't use it as an example :)

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Would it be possible to revamp the Rectangular to Polar Conversion plug-in Source to include Bilinear Sampling?

Few code to change.

I would give a chance to Programmerman (plugin author) to update...

Post your request on his topic... Or update the plugin yourself as the source is provided (I will do it in few days if nobody answers).

Link to comment
Share on other sites

Thanks Madjik, I posted the request in his thread.

I would do it but I am lost when it comes to C#.

 

Take responsibility for your own intelligence. 😉 -Rick Brewster

Link to comment
Share on other sites

  • 4 weeks later...

Tube Effect new version 2007/05/03

What's new:

The two sliders ranges are now : -500% to +500% and default 0%

Horizontal slider is inverted (more 'natural').

Better behave for none square image while moving, if the image leaves the area on a side it will reappear on the other.

The Effect DLL

You can download the effect DLL here: Tube Oblique.dll

Put this file in your c:/program files/Paint.NET/Effects directory. You need to restart Paint.Net.

The Effect is in the Effects menu under Distorts...

Source Code

int Amount1=0;  //[-500,500]Horizontal cylinder factor
int Amount2=0;  //[-500,500]Vertical cylinder factor

void Render(Surface dst, Surface src, Rectangle rect)
{
 PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
 Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();

 float RadiusY =-(float)Amount1 / 100.0f;
 float RadiusX =(float)Amount2 / 100.0f;
 float Distort = 2.0f;

 long SizeX = (long)(selection.Right - selection.Left);
 long SizeY = (long)(selection.Bottom - selection.Top);
 long CenterX = (long)((SizeX / 2.0f)+selection.Left);
 long CenterY = (long)((SizeY / 2.0f)+selection.Top);
 ColorBgra CurrentPixel; 

 for(int y = rect.Top; y < rect.Bottom; y++)
 {
   float AngleY = (float)Math.Asin(Distort *(float)(y - CenterY)/(float)SizeY);
   float srcXd = (float)(Math.Cos(AngleY) * RadiusY * CenterY);
   for (int x = rect.Left; x < rect.Right; x++)
   {
     //CurrentPixel = src.GetBilinearSample(x, y); // Get the current pixel 
     int srcX = (int)Math.IEEERemainder((int)srcXd + x,SizeX);
     if (srcX < selection.Left) srcX+=(int)SizeX;
     if (srcX >= selection.Right) srcX-=(int)SizeX;

     float AngleX = (float)Math.Acos(Distort *(float)(x - CenterX)/(float)SizeX);
     float srcYd = (float)(Math.Sin(AngleX)* RadiusX * CenterX);
     int srcY = (int)Math.IEEERemainder((int)srcYd + y,SizeY);
     if (srcY < selection.Top) srcY+=(int)SizeY;
     if (srcY >= selection.Bottom) srcY-=(int)SizeY;

     CurrentPixel = src.GetBilinearSample(srcX, srcY);
     dst[x,y] = CurrentPixel;
   }
 }
}

Link to comment
Share on other sites

I've always liked this plugin...

Would it be possible to center the effect? That way you wouldn't need to piece the image back together if part of it went of the canvas...

 

Take responsibility for your own intelligence. 😉 -Rick Brewster

Link to comment
Share on other sites

I've always liked this plugin...

Would it be possible to center the effect? That way you wouldn't need to piece the image back together if part of it went of the canvas...

I don't see what you mean!

This effect is built to 'move' lines horizontaly (or columns verticaly), on a curve (half ellispe). So of course the image is wrapping...

Are you asking me to redo a 'sphere' effect?

Link to comment
Share on other sites

Here is what I mean...

Before:

before-1.png

With Tube:

after-1.png

My idea:

myidea.png

Basically I would like the "Paneling" function be automatically done to re-center the image.

 

Take responsibility for your own intelligence. 😉 -Rick Brewster

Link to comment
Share on other sites

Ok I see...

I've tried something that should work:

What's new:

Third slider used for Centered No/Yes

Re-Download the Effect DLL

You can download the effect DLL here: edit

Put this file in your c:/program files/Paint.NET/Effects directory. You need to restart Paint.Net.

The Effect is in the Effects menu under Distorts...

int Amount1=0;  //[-500,500]Horizontal cylinder factor 
int Amount2=0;  //[-500,500]Vertical cylinder factor 
int Amount3=1;  //[0,1]Centered 0=No,1=Yes 

void Render(Surface dst, Surface src, Rectangle rect) 
{ 
 PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds); 
 Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt(); 

 long SizeX = (long)(selection.Right - selection.Left); 
 long SizeY = (long)(selection.Bottom - selection.Top); 
 long CenterX = (long)((SizeX / 2.0f)+selection.Left); 
 long CenterY = (long)((SizeY / 2.0f)+selection.Top); 
 ColorBgra CurrentPixel; 

 float RadiusY = -(float)(Amount1 * CenterY) / 100.0f; 
 float RadiusX =  (float)(Amount2 * CenterX) / 100.0f; 
 float Distort = 2.0f; 


 for(int y = rect.Top; y < rect.Bottom; y++) 
 { 
   for (int x = rect.Left; x < rect.Right; x++) 
   { 
     float AngleY = (float)Math.Asin(Distort *(float)(y - CenterY)/(float)SizeY); 
     float srcXd = (float)(Math.Cos(AngleY) * RadiusY - Amount3 * RadiusY); 
     float srcX = (float)Math.IEEERemainder(srcXd + x,SizeX); 
     if (srcX < selection.Left) srcX+=(int)SizeX; 
     if (srcX >= selection.Right) srcX-=(int)SizeX; 

     float AngleX = (float)Math.Acos(Distort *(float)(x - CenterX)/(float)SizeX); 
     float srcYd = (float)(Math.Sin(AngleX) * RadiusX - Amount3 * RadiusX); 
     float srcY = (float)Math.IEEERemainder(srcYd + y,SizeY); 
     if (srcY < selection.Top) srcY+=(int)SizeY; 
     if (srcY >= selection.Bottom) srcY-=(int)SizeY; 

     CurrentPixel = src.GetBilinearSample(srcX, srcY); 
     dst[x,y] = CurrentPixel; 
   } 
 } 
} 
 

Edit:

changed some int to float in the code

Link to comment
Share on other sites

It works good.

What happened the to great sampling it use to have? :cry:

Not enough sliders?

 

Take responsibility for your own intelligence. 😉 -Rick Brewster

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...