Jump to content

Double Entries for Pixels


Recommended Posts

Hello,

 

I'm having problem with a plugin I'm writing (or at least part of the plugin).

 

What this code does is:

01. Looks for a pixel with a red value of 100

02. Writes to a log file the RGB | HSV | Pixel Coordinates

 

That's about it. It works great (thanks to paul_Nicholls for his post "Append to text file from inside CodeLab code"),

but the problem is that the log is getting double entries for pixels (averaging 2 entries per pixel).

 

I tested it by:

01. Using a pencil set to R:100.

02. Making one pixel dot onto to standard/default white.

03. Selecting an area.

04. Running the plugin.

 

Nine times out of ten the log file shows 2 entries for the one pixel. This is also true even when only the red pixel

is selected.

 

Just wondering if anything can be done to fix this problem. Perhaps paint.net uses overlapping ROI rectangles?

 

I've attached the source code only as you'll want to change the name and location of the log file if you'd like to test

it out on your machines.

 

Any help would be appreciated.

 

-Paul

// Name:

// Submenu:
// Author:

// Title:

// Desc:

// Keywords:

// URL:

// Help:

#region UICode

int Amount1=0;	//[0,100]Slider 1 Description

int Amount2=0;	//[0,100]Slider 2 Description

int Amount3=0;	//[0,100]Slider 3 Description

#endregion
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Render(Surface dst, Surface src, Rectangle rect)  {
 //START: RENDER CODE

     int TOP = rect.Top;
     int BOT = rect.Bottom;
     int LFT = rect.Left;
     int RIT = rect.Right;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     for (int V=TOP; V < BOT; V++)        { //START: VERTICAL: TOP TO BOTTOM LOOP (Y)
         for (int H=LFT; H < RIT; H++)    { //START: HORIZONTAL: LEFT TO RIGHT LOOP (X)
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             ColorBgra CPIX = src[H,V];


             Color STDC = CPIX.ToColor();
             HsvColor CPHSV = HsvColor.FromColor(STDC);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             int CPR = CPIX.R;
             int CPG = CPIX.G;
             int CPB = CPIX.B;
             int CPH = CPHSV.Hue;
             int CPS = CPHSV.Saturation;
             int CPV = CPHSV.Value;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             
if (CPR == 100)                           {
 //START: CPR IF
                 System.IO.StreamWriter SW;
                 SW = System.IO.File.AppendText("C:\\Users\\CTCPublic\\Desktop\\geb\\CoolEdit.txt");
                 
                 
                 SW.WriteLine("R:" + CPR + "," + "G:" + CPG + "," + "B:" + CPB + " |" +
                              "H:" + CPH + "," + "S:" + CPS + "," + "V:" + CPV + " |" + 
                              "coords=" + "V:" + V + "H:" + H);
 
                 SW.Close();
                                                       } //END: CPR IF
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             dst[H,V] = CPIX;

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                                       } //END: LEFT TO RIGHT LOOP
  
                                                     } //END: TOP TO BOTTOM LOOP

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                                       } //END: RENDER CODE

write-tex03.txt

The Rise of the Creative Class

by: Richard Florida

Link to comment
Share on other sites

Build this file to a DLL and install it in Paint.NET. It will not work in CodeLab, it must be built as a DLL in order to work.

 

// Name: Junk
// Force Single Threaded
#region UICode
#endregion

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

    string OutputFile = @"C:\Users\CTCPublic\Desktop\geb\CoolEdit.txt";
    
    StreamWriter SW=File.AppendText(OutputFile);
    for (int y = rect.Top; y < rect.Bottom; y++)
    {
        if (IsCancelRequested)
        {
            SW.Close();
            return;
        }
        for (int x = rect.Left; x < rect.Right; x++)
        {
            ColorBgra CurrentPixel = src[x,y];
            int R = CurrentPixel.R;
            int G = CurrentPixel.G;
            int B = CurrentPixel.B;
            int A = CurrentPixel.A;
            HsvColor hsv = HsvColor.FromColor(CurrentPixel.ToColor());
            int H = hsv.Hue;
            int S = hsv.Saturation;
            int V = hsv.Value;

            if (R == 100)
            {
                SW.WriteLine("R:" + R + ",G:" + G + ",B:" + B +
                             " | H:" + H + ",S:" + S + ",V:" + V +
                             " | coords=V:" + y + ",H:" + x);
            }
        }
    }
    SW.Close();
}
Remember to delete CoolEdit.txt before running the effect otherwise you might get duplicates as the second run will append to the existing file.
Link to comment
Share on other sites

Thanks so much!

 

Is it okay to use CodeLab to build the dll?

 

From the looks of your code, I'm guessing that

   dst.CopySurface(src,rect.Location,rect);
...forces it to be single-threaded? Or is it closing the StreamWriter after all pixels are processed? Just wondering.

 

My C# knowledge isn't very great (and I just want to use it for paint.net plugins anyway), so stuff like "string OutputFile = @..." is awesome.

 

Thanks Again,

P.

The Rise of the Creative Class

by: Richard Florida

Link to comment
Share on other sites

dst.CopySurface(src,rect.Location,rect);
This code simply copies all pixels from the source canvas to the destination canvas. Remember, as a plugin author, you are responsible for writing to all of the pixels on the destination canvas. Since we won't be changing the pixels, I just did a quick copy.

 

// Force Single Threaded
This code forces the compiled DLL to be single threaded. Normally comments are ignored by a compiler and therefore have no effect on the compiled code. CodeLab is a little different. It uses the content of a few comments to change what is compiled for when code is compiled to a DLL.

"Single Threaded" means that the Render function will be called one at a time to process the selection instead of lots of threads calling Render all at the same time.

Because this is done in a single thread, you'll be sure that the output file is only ever opened by one thread at a time.

When an effect is in CodeLab itself, it is running multithreaded. Only the compiled DLL is forced to be single threaded.

Yes, you can use CodeLab to compile the effect. Just ignore the run errors while compiling it.

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