Jump to content

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


tkddude2

Recommended Posts

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()              
                ////);
             //
            }
        }
    }
}

Link to comment
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(';');

 

  • Upvote 1

(September 25th, 2023)  Sorry about any broken images in my posts. I am aware of the issue.

bp-sig.png
My Gallery  |  My Plugin Pack

Layman's Guide to CodeLab

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

  • Upvote 1

 

Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings

 

PdnForumSig2.jpg

Link to comment
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;
            }
        }
    }
}

 

  • Upvote 2

(September 25th, 2023)  Sorry about any broken images in my posts. I am aware of the issue.

bp-sig.png
My Gallery  |  My Plugin Pack

Layman's Guide to CodeLab

Link to comment
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

Link to comment
Share on other sites

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

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

(September 25th, 2023)  Sorry about any broken images in my posts. I am aware of the issue.

bp-sig.png
My Gallery  |  My Plugin Pack

Layman's Guide to CodeLab

Link to comment
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)

  • Upvote 1
Link to comment
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.

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...