Jump to content

So, there seem to be a problem with modulo calculation. (Solved)


Recommended Posts

I have this code right here I have made out of trying something new. And I find that there doesn't seem to be a easy way to preserve 0,255 ranges on Divisive Modulo.

 

// Name: Image Modulo Toolkit
// Submenu: Adjustments
// Author: Reptorian
// Title: Image Modulo Toolkit
// Version: .5
// Desc: Adjust image values based on the logics of Krita Modulo Blending Modes, or G'MIC 'modf' or 'modular_formula'.
// Keywords:
// URL:
// Help:
#region UICode
ListBoxControl Amount1 = 0; // Blending Mode | Modulo | Modulo Continuous | Divisive Modulo
IntSliderControl Amount2 = 255; // [1,255] Maximum Number
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
    // Delete any of these lines you don't need
    Rectangle selection = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
    int CenterX = ((selection.Right - selection.Left) / 2) + selection.Left;
    int CenterY = ((selection.Bottom - selection.Top) / 2) + selection.Top;
    ColorBgra PrimaryColor = EnvironmentParameters.PrimaryColor;
    ColorBgra SecondaryColor = EnvironmentParameters.SecondaryColor;
    int BrushWidth = (int)EnvironmentParameters.BrushWidth;

    ColorBgra CurrentPixel;
    for (int y = rect.Top; y < rect.Bottom; y++)
    {
        if (IsCancelRequested) return;
        for (int x = rect.Left; x < rect.Right; x++)
        {
            CurrentPixel = src[x,y];
            int R = (int)CurrentPixel.R;
            int G = (int)CurrentPixel.G;
            int B = (int)CurrentPixel.B;
            float DivMult= 255/Amount2;
            switch(Amount1)
            {
               case 0: R=(byte)(R%(Amount2+1));
                       G=(byte)(G%(Amount2+1));
                       B=(byte)(B%(Amount2+1));
                       break;
               case 1: int TR=R/(Amount2+1);
                       int TG=G/(Amount2+1);
                       int TB=B/(Amount2+1);
                       bool CR=TR%2==1;
                       bool CG=TG%2==1;
                       bool CB=TB%2==1;
                       if (CR) {R=(byte)(Amount2-(R%(Amount2+1)));} else {R=(byte)(R%(Amount2+1));}
                       if (CG) {G=(byte)(Amount2-(G%(Amount2+1)));} else {G=(byte)(G%(Amount2+1));}
                       if (CB) {B=(byte)(Amount2-(B%(Amount2+1)));} else {B=(byte)(R%(Amount2+1));}
                       break;
              case 2:  float MTR=R%(Amount2+1);
                       float MTG=G%(Amount2+1);
                       float MTB=B%(Amount2+1);
                       MTR*=(float)(DivMult);
                       MTG*=(float)(DivMult);
                       MTB*=(float)(DivMult);
                       int NMTR = (int)(MTR);
                       int NMTG = (int)(MTG);
                       int NMTB = (int)(MTB);
                       R=(byte)(NMTR);
                       G=(byte)(NMTG);
                       B=(byte)(NMTB);
                       break;         
            }
            CurrentPixel = ColorBgra.FromBgra((byte)(B),(byte)(G),(byte)(R),CurrentPixel.A);
            dst[x,y] = CurrentPixel;
        }
    }
}

I know the case 2 could be simpler, but haven't really figured it out.

Edited by Reptillian

G'MIC Filter Developer

Link to comment
Share on other sites

16 minutes ago, Reptillian said:

And I find that there doesn't seem to be a easy way to preserve 0,255 ranges on Divisive Modulo.

 

If you need to clamp the RGB values, you can do this:

CurrentPixel = ColorBgra.FromBgraClamped(B, G, R, CurrentPixel.A);

 

Or did I misunderstand your question?

(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

6 minutes ago, toe_head2001 said:

 

If you need to clamp the RGB values, you can do this:


CurrentPixel = ColorBgra.FromBgraClamped(B, G, R, CurrentPixel.A);

 

Or did I misunderstand your question?

 

You misunderstood. If you use 175 for Divisive Modulo, you'd note that the highest value is not 255, and the expected value is 255. While you shift value, it should behave similar to the first 2 modulo modes. That didn't really work as a solution.

Edited by Reptillian

G'MIC Filter Developer

Link to comment
Share on other sites

CodeLab has Debug Output capabilities; I suggest you use it. Click on the associated Checkbox at the bottom of CodeLab.

 

For example, if you want to evaluate your math expressions, you can do this:

void PreRender(Surface dst, Surface src)
{
    int R = 255;
    float DivMult = 255 / Amount2;
    Debug.WriteLine("DivMult: " + DivMult);

    float MTR = R % (Amount2 + 1);
    Debug.WriteLine("MTR: " + MTR);

    MTR *= (float)(DivMult);
    Debug.WriteLine("MTR: " + MTR);

    int NMTR = (int)(MTR);
    Debug.WriteLine("NMTR: " + NMTR);

    R = (byte)(NMTR);
    Debug.WriteLine("R: " + R);
}

 

  • 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

I don't know if this will solve the problem you're referring to, but I doubt this line does what you want it to do:

float DivMult= 255/Amount2;

Amount2 is an int, as is 255, so an integer divide will be performed, and the (integer) result converted to a float. I suspect that's not what's intended.

 

Try:

float DivMult= 255.0 / (float)Amount2;

(Also, the line should be moved outside the loop. It can be computed once at the top.)

  • Like 1
Link to comment
Share on other sites

I should have mentioned I solved It. Anyways, when I was coding that, I realized that when coding for c#, it is not like c++ or the gmic scripting language and did not taken the account for the need of converting Amount2 into a float. I knew that I have to work with converting types. It was fun doing something different once in a while.

 

 

G'MIC Filter Developer

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