Rick Brewster

CodeLab v4.3 (for advanced users) Released July 13, 2019

Recommended Posts

It is fairly complicated. I just sent Illnab1024 a message to see if he has some sample code. His AlphaMask plugin has this function.

Share this post


Link to post
Share on other sites

void Render(Surface dst, Surface src, Rectangle rect)
{
   for (int y = rect.Top; y < rect.Bottom; y++)
   {
       for (int x = rect.Left; x < rect.Right; x++)
       {
           if (img == null)
               dst[x,y] = src[x,y];
           else
               dst[x,y] = img.GetBilinearSampleWrapped(x,y);
       }
   }
}
protected Surface img
{
   get { if (_img != null)
           return _img; 
         else
         {
           System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(GetImageFromClipboard));
           t.SetApartmentState(System.Threading.ApartmentState.STA); 
           t.Start();
           t.Join();
           return _img;
         }
       }
}
private Surface _img = null;
private void GetImageFromClipboard()
{
   Bitmap aimg = null;
   IDataObject clippy;
   try
   {
       clippy = Clipboard.GetDataObject();
       if (clippy != null)
       {
           aimg = (Bitmap)clippy.GetData(typeof(System.Drawing.Bitmap));
       }
   }
   catch (Exception )
   {
   }
   if (aimg != null)
   {
       _img = Surface.CopyFromBitmap(aimg);
   }
   else
   {
       _img = null;
   }
}

I do NOT advise making threads wildly in CodeLab, but I'm relatively sure it's the only option in the case of the clipboard.

Also, I think you may want to add better error handling for the case of when there's not an image on the clipboard, because calling Clipboard.GetDataObject() that many times will prolly do something awful.

EDIT: Public, private, blah.

Share this post


Link to post
Share on other sites

Also, some fun with networking! A polar distortion based off of an image taken from nik.bot.nu (advice: slightly maybe NSFW).

Supposedly, this HSV algorithm works. I'm too tired to try to understand it atm, so I just threw it in there. It works I suppose. (takes a while to do everything, I think cause of several requests gone by without caching)

#region UICode
int Amount1=10;	//[0,300]Distortion length
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
   Surface img = nikbotImg;
   float[] vector = new float[2]{0,0};
   for (int y = rect.Top; y < rect.Bottom; y++)
   {
       for (int x = rect.Left; x < rect.Right; x++)
       {
           vector = calVector(x,y);
           dst[x,y] = src.GetBilinearSampleWrapped(x+vector[0],y+vector[1]);
       }
   }
}
static string nikbotBrowseUri = "http://nik.bot.nu/browse.fu?cnt=1&pn=0&srt=7&eq=0&rs=0&rt=0&da=7&nw=0";
string imgUri = "http://nik.bot.nu/img/";
string imgName;
Surface nikbotImg
{
   get
   {
       if(_nikbotImg == null)
       {
           getImage();
           return _nikbotImg;
       }
       return _nikbotImg;
   }
}
Surface _nikbotImg = null;
double[] HSVcolor(byte r, byte g, byte 
{   double[] a;
   double R = r/255d, G = g/255d, B = b/255d, v, x, f;
   int i;
   x = min(R, G, ;
   v = max(R, G, ;
   if(v == x) return new double[3]{0, 0, v};
   f = (R == x) ? G - B : ((G == x) ? B - R : R - G);
   i = (R == x) ? 3 : ((G == x) ? 5 : 1);
   a = new double[3]{i - f /(v - x), (v - x)/v, v};
   a[0] = a[0]*((2*Math.PI)/6d);
   return a;
}
double min(double a,double b,double c)
{
   a = Math.Min(a,;
   return Math.Min(a,c);
}
double max(double a,double b,double c)
{
   a = Math.Max(a,;
   return Math.Max(a,c);
}
float[] calVector(int x,int y)
{
   ColorBgra p = nikbotImg[x,y];
   float[] vectorrrrr = new float[2]{0,0};
   double[] HSVal = HSVcolor(p.R, p.G, p.;
   double length, direction;
   length = HSVal[1]*HSVal[2]*(Amount1);
   direction = HSVal[0]; // Shud be radians, I hope.
   vectorrrrr[0] = (float)(Math.Sin(direction)*length);
   vectorrrrr[1] = (float)(Math.Cos(direction)*length);
   return vectorrrrr;
}
void getImage()
{
   System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(nikbotBrowseUri);
   string resultPage = string.Empty;
   using (System.Net.HttpWebResponse httpWebResponse = (System.Net.HttpWebResponse)request.GetResponse())
   {
       using (System.IO.Stream responseStream = httpWebResponse.GetResponseStream())
       {
           using (System.IO.StreamReader reader = new System.IO.StreamReader(responseStream))
           {
               resultPage = reader.ReadToEnd();
           }
       }
   }
   int imgIdx = resultPage.IndexOf("    imgIdx += 28;
   resultPage = resultPage.Remove(0,imgIdx);
   resultPage = resultPage.Remove(resultPage.IndexOf("\""),resultPage.Length-resultPage.IndexOf("\""));
   imgUri += resultPage;
   Image im = null;
   try
   {
       System.Net.HttpWebRequest request2 = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(imgUri);
       request2.Method = "GET";
       request2.Timeout = 10000;
       request2.ProtocolVersion = System.Net.HttpVersion.Version11;
       using (System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request2.GetResponse())
       {
           using (System.IO.Stream responseStream = response.GetResponseStream())
           {
               im = Image.FromStream(responseStream);
           }
       }
   }
   catch (Exception ex)
   {
       MessageBox.Show("Lols, no image for you:"+ex.Message+Environment.NewLine+imgUri);
       return;
   }
   _nikbotImg = Surface.CopyFromBitmap((Bitmap)im);
}

Oh and by the way, I think this effect is simply amazing. Just, a personal note.

Share this post


Link to post
Share on other sites

CodeLab 1.5 released today.

Get the update here: http://www.boltbait.com/pdn/codelab/

I was playing around with text boxes and realized that I had never added the multi-line text box to CodeLab... so I did.

Here is a sample script that takes advantage of the new control:

// Title: BoltBait's Render Text Sample
// Author: BoltBait
// Submenu: Render
// Name: Text
// URL: http://www.BoltBait.com/pdn
#region UICode
string Amount1 = ""; // [1,32767] Text
FontFamily Amount2 = new FontFamily("Arial"); // Font
int Amount3 = 12; // [10,72] Size
byte Amount4 = 1; // [1] Smoothing|None|Anti-Alias|ClearType
ColorBgra Amount5 = ColorBgra.FromBgr(0,0,0); // Color
Pair<double, double> Amount6 = Pair.Create( 0.0 , 0.0 ); // Location
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
   Rectangle selection = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt(); 
   // Reset the destination canvas
   dst.CopySurface(src,rect.Location,rect);
   // Determine where the text will be written
   int column = (int)Math.Round(((Amount6.First + 1) / 2) * (selection.Right - selection.Left));
   int row = (int)Math.Round(((Amount6.Second + 1) / 2) * (selection.Bottom - selection.Top));
   // Create a brush and graphics surface to write on
   SolidBrush Brush1 = new SolidBrush(Amount5.ToColor());
   Graphics g = new RenderArgs(dst).Graphics;
   // specify smoothing mode
   switch (Amount4)
   {
       case 0: // none
           g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
           break;
       case 1: // anti-alias
           g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
           break;
       case 2: // cleartype
           g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
           break;
   }
   // Be sure to clip to our ROI
   g.Clip = new Region(rect);
   // Create a font from user selection
   Font SelectedFont;
   try
   {
       SelectedFont = new Font(Amount2.Name, Amount3);
   }
   catch
   {
       // If font creation fails, use Arial font
       SelectedFont = new Font("Arial", Amount3);
   }
   // Write our text to the canvas
   g.DrawString(Amount1, SelectedFont, Brush1, column, row);
}
 

The code above shows more than just the new multi-line text box, but also how to do font smoothing (or not). Here's what that script builds:

 

Text.png

Share this post


Link to post
Share on other sites

I just updated the script above with an example of 3 types of font smoothing (anti-alias, cleartype, and none).

Share this post


Link to post
Share on other sites

Hi BoltBait,

Thanks for this update, I was looking for the lastest version of codelab because I've encounted some trouble I though it could be solved... But it is not (yet).

codelabpb-1b68f0f.jpg

Could it be possible to have a decimal value for the range and the default values when we build the DLL ?

PS: I haven't tested the text feature yet but I'll do soon as some ideas are poping in my brain. :)

Regards.

Share this post


Link to post
Share on other sites

MadJik, I see the issue and I have sent you a fixed version to test.

(However, please note that the Paint.NET controls only go to 2 decimal places. So, 0.01 will work and 0.001 will not.)

Let me know if it works for you and I'll make an official release.

Share this post


Link to post
Share on other sites

CodeLab 1.6 released today.

Features:

- Float slider bug fix.

- Code Completion. (This is similar to Microsoft's Intellisense.)

- "File>New" Templates for writing complex effects.

Go get it here: http://www.boltbait.com/pdn/CodeLab/

Screenshot:

CodeLab16UI.png

Share this post


Link to post
Share on other sites

I like the new version and it's Auto Completion but the Auto Completion is buggy, sometimes lets say i wrote "CurrentPixel.R" and then add a comma and press space then there often comes an extra R (Actually haven't tried that yet without being buggy in any way)

Share this post


Link to post
Share on other sites

I like the new version and it's Auto Completion but the Auto Completion is buggy, sometimes lets say i wrote "CurrentPixel.R" and then add a comma and press space then there often comes an extra R (Actually haven't tried that yet without being buggy in any way)

Press space or Esc, then comma.

Once the Auto Completion list is visible, there are only certain keys that will finish the code:

Space, Enter, Tab: Replace what is typed with selection

Esc: Cancel

I'll add comma to the first list in the next build.

Share this post


Link to post
Share on other sites

Not to be picky but could you also somehow add ')', ';' and other usually used keys and characters to the list and a way to disable the auto completion?

Share this post


Link to post
Share on other sites

MadJik, here is the code that activates the code completion:

if (e.KeyData == Keys.OemPeriod)

According to the compiler's help:

OemPeriod is defined as "The OEM period key on any country/region keyboard (Windows 2000 or later)."

So, I'm not sure why this isn't working. How do you suggest I handle this?

Share this post


Link to post
Share on other sites

PDN crashed when i wrote

private UnaryPixelOps.Desaturate

and then pressed space

Tried this twice, crashed both times

Edited by Cookies

Share this post


Link to post
Share on other sites

PDN crashed when i wrote

private UnaryPixelOps.Desaturate

and then pressed space

Tried this twice, crashed both times

This repros here. Further, after pressing . the IntelliSense box shows up, but nothing in it.

EDIT: Typing UnaryPixelOps.[space] anywhere also kills it.

Share this post


Link to post
Share on other sites

Thanks for the report. I'll look into it this weekend when I'm feeling better.

Share this post


Link to post
Share on other sites

Yeah, I had a look at it.

I'm not sure why the intellisense window is empty, but that is definately what is causing the problem.

When it comes up blank, just press Esc and it should go away and not cause a crash.

I wasn't really up to doing any work this past weekend, I'll see what I can do this week. Sorry for the delay.

Share this post


Link to post
Share on other sites

Am loving the new Intellisense! A brilliant addition.

I can't get Codelab to accept lambda expressions at all :(. Is it my code or are lambda expressions not compatible/ not implimented?

Share this post


Link to post
Share on other sites

Am loving the new Intellisense! A brilliant addition.

Thanks, that reminds me that I need to publish an update.

I can't get Codelab to accept lambda expressions at all :(. Is it my code or are lambda expressions not compatible/ not implimented?

I'm not sure. Is a reference needed to make them work? If so, I could add it. Just let me know.

Share this post


Link to post
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.