Sign in to follow this  
Followers 0
tkddude2

How do I finish this script of taking information from a string and coloring pixels with it?

10 posts in this topic

I am making a plugin on CodeLab, and I have been having quite a bit of trouble. I want to make a script that takes an input of something like "[10,10;20,20;0.5,0.25,0.9;1][50,60;10,10;0,0,0;1]" and creates a picture out of it. Heres how its suppose to work. 

[posX, posY; sizeX, sizeY, R,B,G; ZIndex] (the ZIndex is not being used yet, because other problems are in the way first, but eventually I would like to have it so that tables with high ZIndex's overwrite the colors of tables with lower ZIndexs)

I want it to paint all of the pixels in the area define by the size and position the RBG given. I have been having trouble debugging this because paint.net keeps on crashing whenever an error exists in the code(because it auto compiles every few seconds). It is VERY annoying. I have tested the string parsing on other programs and am confident that it works, but it still keeps on crashing. Eventually, I want to get rid of the line     String Amount1 = "[10,10;20,20;0.5,0.25,0.9;1][50,60;10,10;0,0,0;1]";   and allow an input from the User Interface Designer. Can anyone out there finish the script for me or point me toward a better plugin creator for Paint.net?

 

 

Here is the code I have so far (and yes the UI code isnt in yet)

 

// Name:
// Submenu:
// Author:
// Title:
// Version:
// Desc:
// Keywords:
// URL:
// Help:


private byte Clamp2Byte(int iValue)
{
    if (iValue<0) return 0;
    if (iValue>255) return 255;
    return (byte)iValue;
}

void Render(Surface dst, Surface src, Rectangle rect) 

    String Amount1 = "[10,10;20,20;0.5,0.25,0.9;1][50,60;10,10;0,0,0;1]";   
    int length = Amount1.Length;
    ColorBgra CurrentPixel; 
    double R, G, B;
    
     //--------------------------------------------------------------------------------------------------------------------   
    for (int y = rect.Top; y < rect.Bottom; y++)        //Replicate background before making changes
    {
        if (IsCancelRequested) return;
        for (int x = rect.Left; x < rect.Right; x++)
        {
            CurrentPixel = src[x,y];
            dst[x,y] = CurrentPixel;
        }
    }       
    
    //--------------------------------------------------------------------------------------------------------------------    
  
    while (length > 10) 
    {
        
       int startPos = Amount1.IndexOf("[");
       int endPos = Amount1.IndexOf("]");
       String newString = Amount1.Substring(startPos, endPos - startPos + 1);  //[-293,-280;585,559;1,1,1;1]
       Amount1 = Amount1.Substring(endPos, Amount1.Length - endPos);
       length = Amount1.Length;
       
       int posX = Int32.Parse(newString.Substring(1, newString.IndexOf(",") - 1)); //-293      
            newString = newString.Substring(newString.IndexOf(","), newString.Length - newString.IndexOf(",")); //,-280;585,559;1,1,1;1]            
       //Console.WriteLine(posX);
       //Console.WriteLine(newString);            
       int posY = Int32.Parse(newString.Substring(1, newString.IndexOf(";") - 1)); //-280
            newString = newString.Substring(newString.IndexOf(";"), newString.Length - newString.IndexOf(";")); //;585,559;1,1,1;1]             
       int sizeX = Int32.Parse(newString.Substring(1, newString.IndexOf(",") - 1)); //585
            newString = newString.Substring(newString.IndexOf(","), newString.Length - newString.IndexOf(",")); //,559;1,1,1;1]              
       int sizeY = Int32.Parse(newString.Substring(1, newString.IndexOf(";") - 1)); //559
            newString = newString.Substring(newString.IndexOf(";"), newString.Length - newString.IndexOf(";")); //;1,1,1;1] 
       R = Int32.Parse(newString.Substring(1, newString.IndexOf(",") - 1));         //1
            newString = newString.Substring(newString.IndexOf(","), newString.Length - newString.IndexOf(",")); //,1,1;1]
       G = Int32.Parse(newString.Substring(1, newString.IndexOf(",", 1) - 1));      //1 the extra one is to start the search after the first comma
             newString = newString.Substring(newString.IndexOf(",", 1), newString.Length - newString.IndexOf(",", 1)); //,1;1]  
       B = Int32.Parse(newString.Substring(1, newString.IndexOf(";") - 1));         //1
              newString = newString.Substring(newString.IndexOf(";"), newString.Length - newString.IndexOf(";")); //;1]            
       int ZIndex = Int32.Parse(newString.Substring(1, newString.IndexOf("]") - 1)); //1
       newString = "";           
 
 
        MessageBox.Show(
             "R = " + R.ToString() + "; " +
             "G = " + G.ToString() + "; " +
             "B = " + B.ToString()
        );
       
       double A = 1;
       
       for(int y = posY; y < posY + sizeY; y++) 
        { 
            for (int x = posX; x < posX + sizeX; x++) 
            {
             CurrentPixel = src[x,y]; 
             int r = (int)Math.Round(R * 255);
             int g = (int)Math.Round(G * 255);
             int b = (int)Math.Round(B * 255);
             int a = (int)Math.Round(A * 255); //opacity              
             //
             //// Reassemble the color from R, G, and B
             //CurrentPixel = ColorBgra.FromBgra(Clamp2Byte(b),Clamp2Byte(g),Clamp2Byte(r),Clamp2Byte(a));
             //dst[x,y] = CurrentPixel; 
             //
                ////MessageBox.Show(
                     ////"R = " + R.ToString() + "; " +
                     ////"G = " + G.ToString() + "; " +
                     ////"B = " + B.ToString() + "; " +
                     ////"X = " + x.ToString() + "; " +    
                     ////"Y = " + y.ToString()              
                ////);
             //
            }
        }
    }
}

0

Share this post


Link to post
Share on other sites
3 hours ago, tkddude2 said:

I have been having trouble debugging this because paint.net keeps on crashing whenever an error exists in the code(because it auto compiles every few seconds). It is VERY annoying.

Sorry, that crashing bug in CodeLab is my fault. It has already been fixed for the next release.

 

 

The issue here is that you're try to parse non-integer as integers.

( 0.5,0.25,0.9 ) <---- these are not integers, nor are they proper values for RGB.

 

 

I would also recommend making use of String.Split()

That will give you an array of all the string groups.

string[] stringArray = newString.Split(';');

 

1

Share this post


Link to post
Share on other sites

To copy the src to the dst surface you can simply use -

dst.CopySurface(src,rect.Location,rect);

Instead of the y & x loops you have at  "//replicate background".

 

 

You could also use the method "Int32Util.ClampToByte()" instead of the 'Clamp2Byte()' method.

 

Hope that helps.

1

Share this post


Link to post
Share on other sites

I've re-written your script.  It has lots of checks, so a bad input doesn't crash it.

It doesn't take into Z-index, but that would fairly easy to add.

 

#region UICode
TextboxControl Amount1 = "[10,10;200,20;255,25,9;1][50,60;10,10;0,0,0;1]"; // [0,255] Weird Notation Here:
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
    dst.CopySurface(src,rect.Location,rect);

    string[] rectanges = Amount1.Split('[');
    foreach (string rectangle in rectanges)
    {
        if (rectangle == string.Empty)
            continue;

        string[] parameterGroups = rectangle.TrimEnd(new char[']']).Split(';');
        if (parameterGroups.Length != 4)
            continue;

        int posX = 0;
        int posY = 0;
        int width = 0;
        int height = 0;
        ColorBgra color = ColorBgra.White;

        string[] pos = parameterGroups[0].Split(',');
        if (pos.Length != 2)
            continue;
        if (!int.TryParse(pos[0], out posX))
            continue;
        if (!int.TryParse(pos[1], out posY))
            continue;

        string[] dims = parameterGroups[1].Split(',');
        if (dims.Length != 2)
            continue;
        if (!int.TryParse(dims[0], out width))
            continue;
        if (!int.TryParse(dims[1], out height))
            continue;

        string[] channels = parameterGroups[2].Split(',');
        if (channels.Length != 3)
            continue;
        if (!byte.TryParse(channels[0], out color.R))
            continue;
        if (!byte.TryParse(channels[1], out color.B))
            continue;
        if (!byte.TryParse(channels[2], out color.G))
            continue;


        for (int y = posY; y < posY + height; y++)
        {
            if (IsCancelRequested) return;
            for (int x = posX; x < posX + width; x++)
            {
                dst[x,y] = color;
            }
        }
    }
}

 

2

Share this post


Link to post
Share on other sites

Thank you to everyone for the help! I was really stuck on my code, and I knew that it looked like a mess(I almost didn't ask for help because it looked so unorganized). But, you guys helped me understand my errors and I cannot thank you enough for showing me the right way to do it.

 

sad crying the office cry thank you

0

Share this post


Link to post
Share on other sites

@ Toe-head: Why not use GDI+ to draw the rectangles?

0

Share this post


Link to post
Share on other sites

Only because tkddude2's original script did not. If I was writing the script for myself, I would most certainly use gdi.

Perhaps tkddude2 just doesn't know about FillRectangle(), and that's why it was not used.

In any case, it's easy enough to swap in.

0

Share this post


Link to post
Share on other sites

@tkddude2 - this is what Toe-Head and I are talking about: http://boltbait.com/pdn/CodeLab/help/tutorial4.asp (see the section on Text).

 

Once you have created a graphics surface (denoted g in the code), you can replace g.drawstring with g.FillRectangle (ref: https://msdn.microsoft.com/en-us/library/windows/desktop/ms535957(v=vs.85).aspx)

1

Share this post


Link to post
Share on other sites

BoltBait.com is run by forum Admin @BoltBait - he develops CodeLab in his spare time. He has a wealth of excellent CodeLab articles on that site.

0

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
Sign in to follow this  
Followers 0