Jump to content

a for loop issue(new effect:ScreenPixle)


Recommended Posts

I made a simple plugin in code lab but I'm having a strange issue.

The lines

int Amount1=1; //[1,20]Size x3

...

int amo1=Amount1*3;

...

for(int y = rect.Top; y < rect.Bottom; y=y+amo1)

{

for (int x = rect.Left; x < rect.Right; x=x+amo1)

{

...

The for loop for x works fine but the same type of setup is not working for y. In the x loop it steps along as expected; the y loop on the other hand runs through ever single line, acting the same as a loop written like so

for(int y = rect.Top; y < rect.Bottom; y++)

. I simply have no idea what is wrong. It could be something else in the code but that seems to be the issue to me. By the way tell me what you think of the effect and thanks for any advice in advance.

Link to comment
Share on other sites

That's because Paint.NET automatically breaks the image up into many segments to automatically multi-thread it. You're only getting rects that are 1 or just a few pixels tall. You can get the bounds of the whole selection via something like

Rectangle selBounds = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();

But don't iterate through the whole thing every time, or you're in for some serious performance problems!

(If you loop through the whole image in the Render function, then Paint.NET will break it into many threads, but each thread will be processing the entire image. Not good for performance.)

xZYt6wl.png

ambigram signature by Kemaru

[i write plugins and stuff]

If you like a post, upvote it!

Link to comment
Share on other sites

Thank you, but I don't really understand how that will help my code. I'm not much of a programmer :oops: . I need to process the image in squares 3 times the user input. Each square needs to split into three equal portions for the RGB values of the square. Also right now it just gets the values from the first pixel in the square. Is there a way to get the average values for the whole square and then render the square? That would improve image quality.

Link to comment
Share on other sites

Something like this:

int Amount1=3;  //[1,20]Size x3

void Render(Surface dst, Surface src, Rectangle rect)
{
 int amo1=Amount1*3;

 ColorBgra CP1;

 for(int y = rect.Top; y < rect.Bottom; ++y)
 {
   int ayr = y % amo1;

   for (int x = rect.Left; x < rect.Right; ++x)
   {
     int axr = x % amo1;

     CP1=src[x,y];

     if(axr      {
       CP1.G=0;
       CP1.B=0;
     }
     else if(axr<(2*amo1/3))
     {
       CP1.R=0;
       CP1.B=0;
     }
     else 
     {
       CP1.R=0;
       CP1.G=0;
     }

     if(ayr      {
       CP1.G=0;
       CP1.B=0;
     }
     else if(ayr<(2*amo1/3))
     {
       CP1.R=0;
       CP1.B=0;
     }
     else 
     {
       CP1.R=0;
       CP1.G=0;
     }

     dst[x,y] = CP1;
   }
 }
}

EDIT:

or like that:

int Amount1=2;  //[0,50]Steps X
int Amount2=2;  //[0,50]Steps Y

void Render(Surface dst, Surface src, Rectangle rect)
{
 int amo1=Amount1*3;
 int amo2=Amount2*3;
 int cx,cy;

 PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
 Rectangle selection = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();

 ColorBgra CP1;

 for(int y = rect.Top; y < rect.Bottom; ++y)
 {
   int ayr = y % amo2;
   cy = y;//ayr * amo2;
   if (cy >= selection.Bottom) cy=y;
   for (int x = rect.Left; x < rect.Right; ++x)
   {
     int axr = x % amo1;
     cx = x;//axr * amo1;
     if (cx >= selection.Right) cx=x;

     CP1=src[cx, cy];

     if((axr        { CP1.G=0; CP1.B=0; }
     else if((axr<(2*amo1/3)) || (ayr<(2*amo2/3)))
       { CP1.R=0; CP1.B=0; }
     else 
       { CP1.R=0; CP1.G=0; }

     dst[x,y] = CP1;
   }
 }
}

I didn't understand the lines like

            CP1.B=(byte)src[x,y];

Link to comment
Share on other sites

Not really but those are cool. If you try the first dll I made it does pretty much what I want it to do. But it runs through every y coordinate. I want the color to stay the same for Amount1 x3 down. kind like the LCD part of this image without the black lines.

http://en.wikipedia.org/wiki/Image:Pixe ... _Pengo.jpg

I think I've made a color assignment function by checking to see if y has changed enough but codelab won't compile it

saying:

Error at line 23: } expected...

Error at line 43: { expected...

I simply don't see how that could be...

lines like

CP1.B=(byte)src[x,y];
CP1.R=0;

are there because I just need to change and clear those two values.

int Amount1=20;	//[1,20]Size x3


private ColorBgra Color(int y, int x, ColorBgra c, int amo1,Surface src, int pass)
       {
          float cut;
          cut=(((float)y/amo1) % 1f)*1000f;
          if(cut==0)
          {
           switch(pass)
           {
            case0:
            c=src[0,0];
            break;

            case1:
            c=src[x,y];
            c.G=0;
            c.B=0;
            break;

            case2:
            CP1.G=(byte)src[x,y];
            CP1.R=0;
            break;

            case3:           
            CP1.B=(byte)src[x,y];
            CP1.G=0;
            break;            
           }
          }  
           return c; 
       }

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

   int amo1=Amount1*3;
   int cy,cx,y1,x1;
   ColorBgra CP1=Color(0,0,src[0,0],amo1,src,0);
   for(int y = rect.Top; y < rect.Bottom; y=y+amo1)
   {


       for (int x = rect.Left; x < rect.Right; x=x+amo1)
       {


           CP1=Color(y,x,CP1,amo1,src,1);


           for(cy=0;cy            {
           for(cx=0;cx<(amo1/3);cx++)
           {
           x1=x+cx;
           y1=y+cy;
           if(x1            {
           if(y1            {            
           dst[x1,y1] = CP1;
           }
           }
           }        
           }
           CP1=Color(y,x,CP1,amo1,src,2);

           for(cy=0;cy            {
           for(cx=(amo1/3);cx<(2*(amo1/3));cx++)
           {
           x1=x+cx;
           y1=y+cy;
           if(x1            {
           if(y1            {            
           dst[x1,y1] = CP1;
           }
           }
           }
           }  
           CP1=Color(y,x,CP1,amo1,src,3);

           for(cy=0;cy            {
           for(cx=(2*(amo1/3));cx            {
           x1=x+cx;
           y1=y+cy;
           if(x1            {
           if(y1            {            
           dst[x1,y1] = CP1;
           }
           }
           }
           }       
       }

   }
}

Link to comment
Share on other sites

in color function, insert a space between case and the value: case0 ?? case 0 !!

and you missed the default case (optional?)

and in case 2 or 3 you don't affect c

and where is defined the CP1?

a working code:

int Amount1=20;   //[1,20]Size x3

ColorBgra CP1;

private ColorBgra Color(int y, int x, ColorBgra c, int amo1,Surface src, int pass)
{
 float cut;
 cut=(((float)y/amo1) % 1f)*1000f;
 if(cut==0)
 {
   switch(pass)
   {
     case 0:
     c=src[0,0];
     break;

     case 1:
     c=src[x,y];
     c.G=0;
     c.B=0;
     break;

     case 2:
     CP1.G=(byte)src[x,y];
     CP1.R=0;
     break;

     case 3:           
     CP1.B=(byte)src[x,y];
     CP1.G=0;
     break;            

     default:
     break;
   }
 }  
 return c; 
}

void Render(Surface dst, Surface src, Rectangle rect)
{
 int amo1=Amount1*3;
 int cy,cx,y1,x1;
 CP1=Color(0,0,src[0,0],amo1,src,0);
 for(int y = rect.Top; y < rect.Bottom; y=y+amo1)
 {
   for (int x = rect.Left; x < rect.Right; x=x+amo1)
   {
     CP1=Color(y,x,CP1,amo1,src,1);
     for(cy=0;cy      {
       for(cx=0;cx<(amo1/3);cx++)
       {
         x1=x+cx;
         y1=y+cy;
         if(x1          {
           if(y1            {            
             dst[x1,y1] = CP1;
           }
         }
       }        
     }
     CP1=Color(y,x,CP1,amo1,src,2);

     for(cy=0;cy      {
       for(cx=(amo1/3);cx<(2*(amo1/3));cx++)
       {
         x1=x+cx;
         y1=y+cy;
         if(x1          {
           if(y1            {            
             dst[x1,y1] = CP1;
           }
         }
       }
     }  
     CP1=Color(y,x,CP1,amo1,src,3);

     for(cy=0;cy      {
       for(cx=(2*(amo1/3));cx        {
         x1=x+cx;
         y1=y+cy;
         if(x1          {
           if(y1            {            
             dst[x1,y1] = CP1;
           }
         }
       }
     }       
   }
 }
}

Link to comment
Share on other sites

Well I'm back to square one. I commented out a control point in the code.

  float cut=0;
 //cut=(((float)y/amo1) % 1f);
 if(cut==0)

It should allow the assignment of c, cR, cG, and cB only when y is at a point where it will complete a RGB(pixel) square. However, it acts very strangely and allows it to assign at points which I can't explain.

int Amount1=9;   //[1,20]Size x3

ColorBgra c,cR,cG,cB;

private void Color(int y, int x, int amo1,Surface src)
{
 float cut=0;
 //cut=(((float)y/amo1) % 1f);
 if(cut==0)
 {
    c=src[x,y];
    cR.R=c.R;
    cR.A=255;
    cG.G=c.G;
    cG.A=255;   
    cB.B=c.B;
    cB.A=255;            
 } 

}

void Render(Surface dst, Surface src, Rectangle rect)
{
 int amo1=Amount1*3;
 int cx,x1;
 for(int y = rect.Top; y < rect.Bottom; y++)
 {
   for (int x = rect.Left; x < rect.Right; x=x+amo1)
   {
     Color(y,x,amo1,src);

       for(cx=0;cx<(amo1/3);cx++)
       {
         x1=x+cx;

         if(x1          {

             dst[x1,y] = cR;

         }
       }       



       for(cx=(amo1/3);cx<(2*(amo1/3));cx++)
       {
         x1=x+cx;

         if(x1          {

             dst[x1,y] = cG;

         }
       }


       for(cx=(2*(amo1/3));cx        {
         x1=x+cx;
         if(x1          {

             dst[x1,y] = cB;

         }     
       }

   }
 }
}

Link to comment
Share on other sites

int Amount1=2;   //[1,20]Size x3

ColorBgra cR,cG,cB;

void Render(Surface dst, Surface src, Rectangle rect)
{
 int amo1=Amount1*3;
 int cx,x1;
 for(int y = rect.Top; y < rect.Bottom; y++)
 {
   if(y%amo1<(amo1/3)) { cR = ColorBgra.FromBgr(0,0,255); cG=ColorBgra.FromBgr(0,255,0); cB=ColorBgra.FromBgr(255,0,0); }
   else if(y%amo1<(2*(amo1/3))) { cB = ColorBgra.FromBgr(0,0,255); cR=ColorBgra.FromBgr(0,255,0); cG=ColorBgra.FromBgr(255,0,0); }
   else  { cG = ColorBgra.FromBgr(0,0,255); cB=ColorBgra.FromBgr(0,255,0); cR=ColorBgra.FromBgr(255,0,0); }
   for (int x = rect.Left; x < rect.Right; x=x+amo1)
   {
     for(cx=0;cx      {
       x1=x+cx;
       if((x1        else if((x1        else if(x1      }       
   }
 }
}

This is not a distort effect, should be texture or render

Link to comment
Share on other sites

Thank you for all this help Madjik. Though I feel I can explain the idea for the plugin better with some examples.

In grid.jpg I've run the pixelate effect making 12x12 blocks of a single color.

Then in grid2.png I've run my screenpixel effect on top of the first pixelate effect.

See how it split each 12x12 block into three parts for it's RGB values? That is exactly what I wanted this effect to do but from the beginning it's always run through ever y coordinate. I didn't want people to have to run two effects to get one result. I'm sure if I understood the pixelate effect I could integrate it into the code.

Link to comment
Share on other sites

Then, this is a distort effect:

int Amount1=4;   //[1,50]Steps X
int Amount2=4;   //[1,50]Steps Y

ColorBgra cR, cG, cB, C1, C2;

void Render(Surface dst, Surface src, Rectangle rect)
{
 int amo1 = Amount1 * 3;
 int amo2 = Amount2 * 3;
 int cx, x1, modeY;
 for(int y = rect.Top; y < rect.Bottom; ++y)
 {
   if (y % amo2 < (amo2 / 3))
     { modeY = 0; }
   else if (y % amo2 < (2 * (amo2 / 3)))
     { modeY = 1; }
   else                                
     { modeY = 2; }

   for (int x = rect.Left; x < rect.Right; x = x + amo1)
   {
     for(cx = 0; cx < amo1; ++cx)
     {
       x1 = x + cx;
       if (x1 < rect.Right)
       {
         C1 = src[x1, y];
         C2 = C1;

         if (modeY==0)
           { cR = ColorBgra.FromBgr(0,0,C1.R); cG=ColorBgra.FromBgr(0,C1.G,0); cB=ColorBgra.FromBgr(C1.B,0,0); }
         else if (y % amo2 < (2 * (amo2 / 3)))
           { cB = ColorBgra.FromBgr(0,0,C1.R); cR=ColorBgra.FromBgr(0,C1.G,0); cG=ColorBgra.FromBgr(C1.B,0,0); }
         else                                
           { cG = ColorBgra.FromBgr(0,0,C1.R); cB=ColorBgra.FromBgr(0,C1.G,0); cR=ColorBgra.FromBgr(C1.B,0,0); }

         if (cx < (amo1 / 3)) 
           { C2 = cR; }
         else if (cx < (2 * (amo1 / 3))) 
           { C2 = cG; }
         else
           { C2 = cB; }

         dst[x1, y] = C2; 
         // or this: (uncomment) 
         //dst[x1, y] = ColorBgra.FromBgra((byte)((C1.B + C2. / 2),(byte)((C1.G + C2.G) / 2),(byte)((C1.R + C2.R) / 2),(byte)((C1.A + C2.A) / 2));
       }
     }       
   }
 }
}

Link to comment
Share on other sites

That's a good bit of code, MadJik. I wish it was what I wanted but it's an entirely different effect. The effect the I envisioned would be the Pixelate effect only it split each block into three part. What you're made is like an overlay. The original code almost work but as the topic of this thread points out I had an issue with the y variable not taking the right steps in it's for loop. And as was pointed out by pyrochild

Paint.NET automatically breaks the image up into many segments to automatically multi-thread it.
I've spent this whole time, with your help, trying to find a work around for that. But any code that I've made is either broken or does the very same thing as the first code. In the end I know that I should find a more advanced way of doing to, like the Pixelate effect. But that's beyond me right now. I was so close this time but PDN's API has beaten me again. Thank you for you help, MadJik.
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...