Reptillian

Image Modulo Toolkit

Recommended Posts

Even though I have done this sort of thing for G'MIC-QT as a cli command, I decided to make it as a plugin just out of doing something different. What this plugin does is modulo functions, but on the end of modulo expression, the value is added by 1. Essentially useful for gradient map preparation, and that's the main reason why this exist. It can also be used for glitch art.

 

Plugin Download - Image Modulo Toolkit.dll

 

After you install the plugin, it's under Adjustments menu.

 

Here's examples of how it works using various Mode option and 64 as the maximum resulting number.

 

Target Image

 

uEqws17.png

 

Regular Modulo

 

0HtqEwz.png

 

Regular Modulo Continuous

 

f85lS0R.png

 

Divisive Modulo

 

NT4NAqO.png

 

Divisive Modulo Continuous

 

Vb2ArrX.png

 

Modulo Addition

 

FU15Z0T.png

 

Modulo Addition Continuous

 

uteFLCj.png

 

-------------

 

License : GPLv3

 

Source code -

 

// Name: Image Modulo Toolkit
// Submenu: Adjustment
// Author: Reptorian
// Title: Image Modulo Toolkit
// Version: 1
// Desc: Adjust image values based on I%(Amount+1)
// Keywords: Modulo
// URL:
// Help:
#region UICode
ListBoxControl<ModuloMode> moduloMode = ModuloMode.Modulo; // Mode | Modulo | Modulo Continuous | Divisive Modulo | Divisive Modulo Continuous | Modulo Addition | Modulo Addition Continuous
IntSliderControl maxNumber = 255; // [1,255] Maximum Number
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
    ColorBgra CurrentPixel;
    float DivMult = 255f / maxNumber;

    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 = CurrentPixel.R;
            int G = CurrentPixel.G;
            int B = CurrentPixel.B;

            switch (moduloMode)
            {
                case ModuloMode.Modulo:
                    R = (byte)(R % (maxNumber + 1));
                    G = (byte)(G % (maxNumber + 1));
                    B = (byte)(B % (maxNumber + 1));
                    break;
                case ModuloMode.ModuloContinuous:
                    int TR = R / (maxNumber + 1);
                    int TG = G / (maxNumber + 1);
                    int TB = B / (maxNumber + 1);
                    R = (TR % 2 == 1) ? (byte)(maxNumber - (R % (maxNumber + 1))) : (byte)(R % (maxNumber + 1));
                    G = (TG % 2 == 1) ? (byte)(maxNumber - (G % (maxNumber + 1))) : (byte)(G % (maxNumber + 1));
                    B = (TB % 2 == 1) ? (byte)(maxNumber - (B % (maxNumber + 1))) : (byte)(R % (maxNumber + 1));
                    break;
                case ModuloMode.DivisiveModulo:
                    if (maxNumber != 1)
                    {
                        R = (byte)(R * DivMult);
                        G = (byte)(G * DivMult);
                        B = (byte)(B * DivMult);
                    }
                    break;
                case ModuloMode.DivisiveModuloContinuous:
                    if (maxNumber != 1)
                    {
                        float MR = R * DivMult;
                        float MG = G * DivMult;
                        float MB = B * DivMult;
                        int CR2 = (int)(MR / 256);
                        int CG2 = (int)(MG / 256);
                        int CB2 = (int)(MB / 256);
                        R = (CR2 % 2 == 0) ? (int)(MR) % 256 : 255 - ((int)(MR) % 256);
                        G = (CG2 % 2 == 0) ? (int)(MG) % 256 : 255 - ((int)(MG) % 256);
                        B = (CB2 % 2 == 0) ? (int)(MB) % 256 : 255 - ((int)(MB) % 256);
                    }
                    break;
                case ModuloMode.ModuloAddition:
                    R = (byte)((R + maxNumber) % 256);
                    G = (byte)((G + maxNumber) % 256);
                    B = (byte)((B + maxNumber) % 256);
                    break;
                case ModuloMode.ModuloAdditionContinuous:
                    R = ((R + maxNumber) > 255) ? (int)(255 - (R + maxNumber) % 256) : R + maxNumber;
                    G = ((G + maxNumber) > 255) ? (int)(255 - (G + maxNumber) % 256) : G + maxNumber;
                    B = ((B + maxNumber) > 255) ? (int)(255 - (B + maxNumber) % 256) : B + maxNumber;
                    break;
            }

            dst[x, y] = ColorBgra.FromBgraClamped(B, G, R, CurrentPixel.A);
        }
    }
}

enum ModuloMode
{
    Modulo,
    ModuloContinuous,
    DivisiveModulo,
    DivisiveModuloContinuous,
    ModuloAddition,
    ModuloAdditionContinuous
}

 

 

EDIT: @toe_head2001 has provided cleaner code of the current plugin. So I inserted it in here for quicker access.

 

Edited by Reptillian
More trustworthy source.
  • Like 1

Share this post


Link to post
Share on other sites

Thanks for the Modulo plugin Toolkit!
I have tested it with gray scale and full 24 bit color image, and a few in between.


I love the Adjustment Effect!

Before I was using the Metalize Effect to achieve what I needed,

but your Adjustment appears to have greater variation yet it is simple to use.

Edited by HyReZ

Share this post


Link to post
Share on other sites

If you're interested in some feedback for your C# code, I've made some cleanups to your code. Hopefully you'll learn something new. :)

 

Spoiler

// Name: Image Modulo Toolkit
// Submenu: Adjustment
// Author: Reptorian
// Title: Image Modulo Toolkit
// Version: 1
// Desc: Adjust image values based on I%(Amount+1)
// Keywords: Modulo
// URL:
// Help:
#region UICode
ListBoxControl<ModuloMode> moduloMode = ModuloMode.Modulo; // Mode | Modulo | Modulo Continuous | Divisive Modulo | Divisive Modulo Continuous | Modulo Addition | Modulo Addition Continuous
IntSliderControl maxNumber = 255; // [1,255] Maximum Number
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
    ColorBgra CurrentPixel;
    float DivMult = 255f / maxNumber;

    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 = CurrentPixel.R;
            int G = CurrentPixel.G;
            int B = CurrentPixel.B;

            switch (moduloMode)
            {
                case ModuloMode.Modulo:
                    R = (byte)(R % (maxNumber + 1));
                    G = (byte)(G % (maxNumber + 1));
                    B = (byte)(B % (maxNumber + 1));
                    break;
                case ModuloMode.ModuloContinuous:
                    int TR = R / (maxNumber + 1);
                    int TG = G / (maxNumber + 1);
                    int TB = B / (maxNumber + 1);
                    R = (TR % 2 == 1) ? (byte)(maxNumber - (R % (maxNumber + 1))) : (byte)(R % (maxNumber + 1));
                    G = (TG % 2 == 1) ? (byte)(maxNumber - (G % (maxNumber + 1))) : (byte)(G % (maxNumber + 1));
                    B = (TB % 2 == 1) ? (byte)(maxNumber - (B % (maxNumber + 1))) : (byte)(R % (maxNumber + 1));
                    break;
                case ModuloMode.DivisiveModulo:
                    if (maxNumber != 1)
                    {
                        R = (byte)(R * DivMult);
                        G = (byte)(G * DivMult);
                        B = (byte)(B * DivMult);
                    }
                    break;
                case ModuloMode.DivisiveModuloContinuous:
                    if (maxNumber != 1)
                    {
                        float MR = R * DivMult;
                        float MG = G * DivMult;
                        float MB = B * DivMult;
                        int CR2 = (int)(MR / 256);
                        int CG2 = (int)(MG / 256);
                        int CB2 = (int)(MB / 256);
                        R = (CR2 % 2 == 0) ? (int)(MR) % 256 : 255 - ((int)(MR) % 256);
                        G = (CG2 % 2 == 0) ? (int)(MG) % 256 : 255 - ((int)(MG) % 256);
                        B = (CB2 % 2 == 0) ? (int)(MB) % 256 : 255 - ((int)(MB) % 256);
                    }
                    break;
                case ModuloMode.ModuloAddition:
                    R = (byte)((R + maxNumber) % 256);
                    G = (byte)((G + maxNumber) % 256);
                    B = (byte)((B + maxNumber) % 256);
                    break;
                case ModuloMode.ModuloAdditionContinuous:
                    R = ((R + maxNumber) > 255) ? (int)(255 - (R + maxNumber) % 256) : R + maxNumber;
                    G = ((G + maxNumber) > 255) ? (int)(255 - (G + maxNumber) % 256) : G + maxNumber;
                    B = ((B + maxNumber) > 255) ? (int)(255 - (B + maxNumber) % 256) : B + maxNumber;
                    break;
            }

            dst[x, y] = ColorBgra.FromBgraClamped(B, G, R, CurrentPixel.A);
        }
    }
}

enum ModuloMode
{
    Modulo,
    ModuloContinuous,
    DivisiveModulo,
    DivisiveModuloContinuous,
    ModuloAddition,
    ModuloAdditionContinuous
}

 

 

  • Upvote 2

Share this post


Link to post
Share on other sites
28 minutes ago, toe_head2001 said:

If you're interested in some feedback for your C# code, I've made some cleanups to your code. Hopefully you'll learn something new. :)

 

  Reveal hidden contents


// Name: Image Modulo Toolkit
// Submenu: Adjustment
// Author: Reptorian
// Title: Image Modulo Toolkit
// Version: 1
// Desc: Adjust image values based on I%(Amount+1)
// Keywords: Modulo
// URL:
// Help:
#region UICode
ListBoxControl<ModuloMode> moduloMode = ModuloMode.Modulo; // Mode | Modulo | Modulo Continuous | Divisive Modulo | Divisive Modulo Continuous | Modulo Addition | Modulo Addition Continuous
IntSliderControl maxNumber = 255; // [1,255] Maximum Number
#endregion

void Render(Surface dst, Surface src, Rectangle rect)
{
    ColorBgra CurrentPixel;
    float DivMult = 255f / maxNumber;

    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 = CurrentPixel.R;
            int G = CurrentPixel.G;
            int B = CurrentPixel.B;

            switch (moduloMode)
            {
                case ModuloMode.Modulo:
                    R = (byte)(R % (maxNumber + 1));
                    G = (byte)(G % (maxNumber + 1));
                    B = (byte)(B % (maxNumber + 1));
                    break;
                case ModuloMode.ModuloContinuous:
                    int TR = R / (maxNumber + 1);
                    int TG = G / (maxNumber + 1);
                    int TB = B / (maxNumber + 1);
                    R = (TR % 2 == 1) ? (byte)(maxNumber - (R % (maxNumber + 1))) : (byte)(R % (maxNumber + 1));
                    G = (TG % 2 == 1) ? (byte)(maxNumber - (G % (maxNumber + 1))) : (byte)(G % (maxNumber + 1));
                    B = (TB % 2 == 1) ? (byte)(maxNumber - (B % (maxNumber + 1))) : (byte)(R % (maxNumber + 1));
                    break;
                case ModuloMode.DivisiveModulo:
                    if (maxNumber != 1)
                    {
                        R = (byte)(R * DivMult);
                        G = (byte)(G * DivMult);
                        B = (byte)(B * DivMult);
                    }
                    break;
                case ModuloMode.DivisiveModuloContinuous:
                    if (maxNumber != 1)
                    {
                        float MR = R * DivMult;
                        float MG = (float)(G * DivMult);
                        float MB = (float)(B * DivMult);
                        int CR2 = (int)(MR / 256);
                        int CG2 = (int)(MG / 256);
                        int CB2 = (int)(MB / 256);
                        R = (CR2 % 2 == 0) ? (int)(MR) % 256 : 255 - ((int)(MR) % 256);
                        G = (CG2 % 2 == 0) ? (int)(MG) % 256 : 255 - ((int)(MG) % 256);
                        B = (CB2 % 2 == 0) ? (int)(MB) % 256 : 255 - ((int)(MB) % 256);
                    }
                    break;
                case ModuloMode.ModuloAddition:
                    R = (byte)((R + maxNumber) % 256);
                    G = (byte)((G + maxNumber) % 256);
                    B = (byte)((B + maxNumber) % 256);
                    break;
                case ModuloMode.ModuloAdditionContinuous:
                    R = ((R + maxNumber) > 255) ? (int)(255 - (R + maxNumber) % 256) : R + maxNumber;
                    G = ((G + maxNumber) > 255) ? (int)(255 - (G + maxNumber) % 256) : G + maxNumber;
                    B = ((B + maxNumber) > 255) ? (int)(255 - (B + maxNumber) % 256) : B + maxNumber;
                    break;
            }

            dst[x, y] = ColorBgra.FromBgraClamped(B, G, R, CurrentPixel.A);
        }
    }
}

enum ModuloMode
{
    Modulo,
    ModuloContinuous,
    DivisiveModulo,
    DivisiveModuloContinuous,
    ModuloAddition,
    ModuloAdditionContinuous
}

 

 

This is just once in a while thing I just did. Any changes as in cleanup or new features in codes, I'll be putting it in the first post and the first post can be edited if I haven't. I don't plan to work on it anymore.

Share this post


Link to post
Share on other sites

It definitely helps to speed things up on a few techniques. (post image is down so I can't post a result)

 

Possibly tell people where to find it ?  I checked all sub menus before looking at the source code and realising it was in Adjustments

 

 

Share this post


Link to post
Share on other sites
6 hours ago, welshblue said:

It definitely helps to speed things up on a few techniques. (post image is down so I can't post a result)

 

Possibly tell people where to find it ?  I checked all sub menus before looking at the source code and realising it was in Adjustments

 

 

On the question, it's done. What other uses you found other than gradient map preparation or glitch art?

Share this post


Link to post
Share on other sites

I'm thinking of a better name. Is 'Modulus Operation' is a better name or is 'Modular Formula' better for this plugin. The second one tells what it does better than the first in my opinion.

Edited by Reptillian

Share this post


Link to post
Share on other sites
18 hours ago, Reptillian said:

What other uses you found other than gradient map preparation or glitch art?

 

A couple of steps before running Modulo (Splinter/ Texture Shader) but then running it made this initial text, before putting my own spin on it

 

modulo-2.png

 

 

  • Like 3

Share this post


Link to post
Share on other sites
On 12/10/2019 at 2:54 AM, welshblue said:

I checked all sub menus before looking at the source code and realizing it was in Adjustments

Before I added my comment above, I had to use the Plugin Browser to find where this plugin resided.
There have been a few times where the creator of a plugin failed to include information about where the plugin could be found.
I see that Reptillian has corrected this omission.

Share this post


Link to post
Share on other sites
1 hour ago, lynxster4 said:

That text looks super-clean @welshblue!  😊  I just love text-effects! <3

 

Thanks Lynxster' ... me too  ... out of all the things I 'do' - text effects are the most satisfying for me.  The satisfaction of experiments turning out good  

All thanks to Rick and all the plugin authors tho'

 

@HyReZ ... TBH if I'd have read your post properly, it would have saved a few minutes

Edited by welshblue

Share this post


Link to post
Share on other sites

First post edited, ditched mediafire and uploaded directly to this site. Now you won't have to get bombarded by ads just to download.

Edited by Reptillian

Share this post


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