Jump to content

Reptillian

Members
  • Posts

    1,239
  • Joined

  • Last visited

  • Days Won

    18

Posts posted by Reptillian

  1. On 6/2/2020 at 4:20 AM, Foxxey said:

    This denoise plugin is just what i needed! Its even better than paint.net's one. Ik this post is 10 years old, but if you're still there please publish the code. I wanna know how this works.

    I don't think the OP will be back. However, I will recommend you to learn kernel processing first, and then search for algorithm on denoising after. It's too late for anyone for the OP to ask for the OP, nor will anyone provide you the source without permission of the OP. I think that the plugin made by @ncoquard would require multi-threaded processing.

  2. I believe G'MIC-QT can do that though you would need to code it and I don't feel like making a sample code for you to work from. Same to ImageMagick.

     

    Two forums I will refer you to

    https://www.imagemagick.org/discourse-server/

    https://discuss.pixls.us/

     

    The bottom one refers to G'MIC-QT though you can ask for ImageMagick there. Ask your G'MIC-QT or ImageMagick question, and you'll get your answer.

  3. 4 hours ago, Djisves said:

    Can you give details please?

    Done. 1st requires a new algorithm that is fast. 2nd is a issue that I can't seem to get around. Both gmic-qt and pdn plugin has this issue though they're rare in both case.

     

    I do have a theory on solving the first one though results would be a little different.

    • Upvote 1
  4. One more question. What if I want a different view and/or avoid affecting the canvas during modifying setting. One example of a G'MIC filter that needs both of them is the Non-Isometric RPG Tiler (Interactive). I believe that you need to create an auxiliary surface to render the effect, and then send it to a preview window within the GUI. Rendering the end result after the interactive window is what comes after the prerender. Right?

  5. This is a distortion plugin that can be found under 'effect/distort'. What this does is shift pixels to boundary with the option to set direction, influence level, threshold level, and position.

     

    Note: There is two difficult to fix bug. If someone wants to try fixing it, then you're more than welcome to, but please share the changes if you do.

     

    1. Transparent dots appears with some settings.

     

    2. Very rarely, the plugin crash. Wait for the render to finish before changing settings.

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

    Here's the test image which is a strange attractor. (IMGUR doesn't support alpha)

     

    qx9mKr0.png

     

    With setting on position -53% ; Influence - 71% ; Threshold - 70 ; Axis to Vertical.

     

    fpzDrUs.png


    And of course, the obligatory interface picture

     

    pJaT6Mk.png

     

    To download this plugin -> Shifted Group Pixel to Boundary.dll

     

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

    License : CeCiLL v2.0 - https://cecill.info/licences/Licence_CeCILL_V2-en.html

     

    Codelab Source code

     

    // Name: Axis-Based Shift Grouped Pixel to Boundary
    // Submenu: Effects / Distortion
    // Author: Reptorian
    // Title: Axis-Based Shift Grouped Pixel to Boundary
    // Version: 0.7
    // Desc: Converted from G'MIC-QT rep_sptbwgp cli filter which is also created by Reptorian.
    // Keywords: Gravity
    // URL: https://forums.getpaint.net/profile/85868-reptillian/
    // Help:
    #region UICode
    DoubleSliderControl positionperc = -100; // [-100,100] Position of Pixels (%)
    DoubleSliderControl influenceperc = 100; // [0,100] Influence Factor (%)
    IntSliderControl alpha_threshold = 255; // [1,255] Alpha Threshold
    ListBoxControl axis = 1; // Axis|Horizontal|Vertical
    #endregion

    int[] rowNonZeroAlphas = null;
    int[] columnNonZeroAlphas = null;
    ColorBgra[,] altsrf = null;

    void PreRender(Surface dst, Surface src)
    {
        int w=src.Width,h=src.Height;
        columnNonZeroAlphas = new int[w];rowNonZeroAlphas = new int[h];
        altsrf = new ColorBgra[w,h];
        int non_alpha_count = 0;
        int tx,ty,nx,ny,fx,fy,N;
        double tny,tnx;
        
        double position = (positionperc / 100 + 1) / 2;
        double influence_factor = influenceperc / 100;
        double invert_factor = 1 - influence_factor;
        
        if (axis==1)
        {
            for (int x = 0 ; x < w ; x++)
            {
                non_alpha_count = 0 ;            
                for (int y = 0; y < h; y++){if (src[x,y].A >= alpha_threshold){non_alpha_count++;}}
                columnNonZeroAlphas[x] = non_alpha_count ;
            }
            
            for (int x = 0 ; x < w ; x++)
            {
                ny = h - 1;
                if (columnNonZeroAlphas[x] != 0)
                {
                    N = columnNonZeroAlphas[x];
                    ty = h - N;
                    ny-=(int)(Math.Round(ty * position));
                    for (int y = h - 1 ; y >= 0 ; y--)
                    {
                        if (N != 0)
                        {
                            if (src[x,y].A >= alpha_threshold)
                            {
                                tny = influence_factor * (double)(ny) + invert_factor * (double)(y);
                                
                                if (position == 1)
                                { fy = (int)(Math.Floor(tny)) ; }
                                else
                                { fy = (int)(Math.Ceiling(tny)) ; }
                                
                                N--;
                                altsrf[x,fy] = src[x,y] ;
                                ny--;                            
                            }
                        }
                        else {break;}
                    }
                }
            }
        }
        else
        {
            for (int y = 0 ; y < h ; y++)
            {
                non_alpha_count = 0 ;            
                for (int x = 0; x < w; x++){if (src[x,y].A >= alpha_threshold){non_alpha_count++;}}
                rowNonZeroAlphas[y] = non_alpha_count ;
            }
            
            for (int y = 0 ; y < h ; y++)
            {
                nx = 0;
                if (rowNonZeroAlphas[y] != 0)
                {
                    N = rowNonZeroAlphas[y];
                    tx = w - N;
                    nx+=(int)(Math.Round(tx * position));
                    for (int x = 0 ; x < w ; x++)
                    {
                        if (N != 0)
                        {
                            if (src[x,y].A >= alpha_threshold)
                            {
                                tnx = influence_factor * (double)(nx) + invert_factor * (double)(x);
                                
                                if (position == 1)
                                { fx = (int)(Math.Ceiling(tnx)) ; }
                                else
                                { fx = (int)(Math.Floor(tnx)) ; }
                                
                                N--;
                                altsrf[fx,y] = src[x,y] ;
                                nx++;                            
                            }
                        }
                        else {break;}
                    }
                }
            }
        }
    }

    void Render(Surface dst, Surface src, Rectangle rect)
    {
        Rectangle selection = EnvironmentParameters.SelectionBounds;
        for (int y = rect.Top; y < rect.Bottom; y++)
        {
            if (IsCancelRequested) return;
            for (int x = rect.Left; x < rect.Right; x++)
            {
                dst[x,y] = altsrf[x,y] ;
            }
        }
    }

     

     

    G'MIC-QT rep_sptbwgp source code

     

    #@cli rep_sptbwgp: (eq. to rep_shift_pixel_to_boundary_with_group_pixels)
    rep_sptbwgp: rep_shift_pixel_to_boundary_with_group_pixels $*
    #@cli rep_shift_pixel_to_boundary_with_group_pixels: -1<=_position<=1, _axis={ 0=Horizontal | 1=Vertical }, 0<=_influence_factor<=1, _threshold>=0,_channel_mode
    #@cli : Shifts pixels to boundary by percentage using grouped pixels. position less than .5 means shift will be negative, and position greater than .5 means shift will be positive.
    #@cli : Assign an argument to _channel_mode if you want to disable restricting effect on alpha channel or avoid manipulating 4 channels image in case of CMYKA image. Only use in rare cases!
    #@cli : Default values: '_position=-1','_axis=1','_influence_factor=1','_threshold=0','_channel_mode='
    rep_shift_pixel_to_boundary_with_group_pixels:
    skip ${1=-1},${2=1},${3=1},${4=0},${5=}
    any_channels=0
    tcr=3
    influence_factor={min(abs($3),1)}
    position={(($1+1)/2)}
    if $4>0 m "sptbwgp_remove_alpha_threshold : f i>=$4?i"
    else    m "sptbwgp_remove_alpha_threshold : f i?i"
    fi
    if $4>0 m "sptbwgp_filter_nonzero : 100%,100%,100%,1,i(#0,x,y,z,s#-1-1)>=$4?1"
    else    m "sptbwgp_filter_nonzero : 100%,100%,100%,1,i(#0,x,y,z,s#-1-1)?1"
    fi
    if $2 m "sptbwgp_create_strip : {w},1,1,1,sum(crop(#-1,x,0,0,0,1,h#-1,1,1))"
    else  m "sptbwgp_create_strip : {h},1,1,1,sum(crop(#-1,0,x,0,0,w#-1,1,1,1))"
    fi
    if   $position<0 position=0
    elif $position>1 position=1
    fi
    if narg($5)
        if $5>=0
            tcr+=1
        else
            any_channels=1
        fi
    fi
    if $influence_factor
        repeat $! l[$>]
            if (s==2||s>$tcr)||$any_channels
                tic
                sh {s-1} sptbwgp_remove_alpha_threshold. rm.
                sptbwgp_filter_nonzero.
                sptbwgp_create_strip
                alpinfo={crop(i#-1)}
                rm[-2,-1]
                if $2 100%,100%,100%,100%,begin(alpi=[$alpinfo];);if(alpi[x]==h,I#0);
                else  100%,100%,100%,100%,begin(alpi=[$alpinfo];);if(alpi[y]==w,I#0);
                fi
                eval ${-math_lib}"            
                    const influence_factor="$influence_factor";
                    const invert_factor=1-influence_factor;
                    const position="$position";
                    const alp=s-1;
                    alpi=["$alpinfo"];
                    if($2
                    ,
                        if(position==1
                        ,func(a)=ceil(a);
                        ,func(a)=floor(a);
                        );
                    ,
                        if(position==1
                        ,func(a)=floor(a);
                        ,func(a)=ceil(a);
                        );
                    );
                    if($2,
                        for(xx=0,xx<w,xx++,
                            nyy=h-1;
                            if(alpi[xx]&&alpi[xx]<h,
                                N=alpi[xx];
                                tyy=h-N;
                                nyy-=tyy*position;
                                for(yy=h-1,yy>-1,yy--,
                                    if(N,
                                        if(i(#0,xx,yy,z,alp),
                                            N--;
                                            tnyy=influence_factor*nyy+invert_factor*yy;
                                            I(#1,xx,func(tnyy))=I(#0,xx,yy);
                                            nyy--;
                                        );
                                        ,break();
                                    );
                                );
                            );
                        );
                    ,
                        for(yy=0,yy<h,yy++,
                            nxx=0;
                            if(alpi[yy]&&alpi[yy]<w,
                                N=alpi[yy];
                                txx=w-N;
                                nxx+=txx*position;
                                for(xx=0,xx<w,xx++,
                                    if(N,
                                        if(i(#0,xx,yy,z,alp),
                                            N--;
                                            tnxx=influence_factor*nxx+invert_factor*xx;
                                            I(#1,func(tnxx),yy)=I(#0,xx,yy);
                                            nxx++;
                                        );
                                        ,break();
                                    );
                                );
                            );
                        );
                    );
                "
                rm..
                toc
            fi
        endl done
    fi
    uncommand sptbwgp_filter_nonzero,sptbwgp_create_strip,sptbwgp_remove_alpha_threshold

    #@gui Grouped Pixel Axis-Based Shift : fx_rep_sptbwgp,fx_rep_sptbwgp_preview
    #@gui : note=note("Based off MadJik's Paint.NET Gravity Plugin. New feature are shift position, and influence factor."),sep=separator()
    #@gui : Shift Position (%)=float(0,-100,100)
    #@gui : Influence Factor (%)=float(0,0,100)
    #@gui : Threshold (%)=float(0,0,100)
    #@gui : Axis=choice(0,"Horizontal","Vertical")
    #@gui : sep=separator(), Preview Type=choice("Full","Forward Horizontal","Forward Vertical","Backward Horizontal","Backward Vertical","Duplicate Top","Duplicate Left","Duplicate Bottom","Duplicate Right","Duplicate Horizontal","Duplicate Vertical","Checkered","Checkered Inverse"), Preview Split = point(50,50,0,0,200,200,200,0,10)_0
    #@gui : sep=separator(), note=note("<small>Author: Reptorian. Latest Update: <i>2019/5/14</i>.</small>")
    fx_rep_sptbwgp:
    position={$1%}
    axis=$4
    threshold={$3%*255}
    influence={$2%}
    rep_sptbwgp $position,$axis,$influence,$threshold

    • Upvote 1
  6. Given how simple the water example is, I think I feel confident about no longer needing to manually convert gmic code into c#. I will have to try this.

     

    I do have only two question though.

    1) Does gmic command "to $_host" shows paintdotnet on canvas?

    2) Is it possible to pass on clipboard image and use [1]? You noted [0] is a layer in gmic.

  7. @MJW Your solution worked!

     

    Releasing the code here for testing purpose.

     

     

    // Name: Axis-Based Shift Grouped Pixel to Boundary
    // Submenu: Effects / Distortion
    // Author: Reptorian
    // Title: Axis-Based Shift Grouped Pixel to Boundary
    // Version: 1.0
    // Desc: Extended version of Gravity by MadJik. Converted from G'MIC-QT rep_sptbwgp cli filter which is also created by Reptorian.
    // Keywords: Gravity
    // URL: https://forums.getpaint.net/profile/85868-reptillian/
    // Help:
    #region UICode
    DoubleSliderControl positionperc = -100; // [-100,100] Position of Pixels (%)
    DoubleSliderControl influenceperc = 100; // [0,100] Influence Factor (%)
    IntSliderControl alpha_threshold = 255; // [1,255] Alpha Threshold
    ListBoxControl axis = 1; // Axis|Horizontal|Vertical
    #endregion

     

    int[] rowNonZeroAlphas = null;
    int[] columnNonZeroAlphas = null;
    ColorBgra[,] altsrf = null;

     

    void PreRender(Surface dst, Surface src)
    {
        int w=src.Width,h=src.Height;
        columnNonZeroAlphas = new int[w];rowNonZeroAlphas = new int[h];
        altsrf = new ColorBgra[w,h];
        int non_alpha_count = 0;
        int tx,ty,nx,ny,fx,fy,N;
        double tny,tnx;
        
        double position = (positionperc / 100 + 1) / 2;
        double influence_factor = influenceperc / 100;
        double invert_factor = 1 - influence_factor;
        
        if (axis==1)
        {
            for (int x = 0 ; x < w ; x++)
            {
                non_alpha_count = 0 ;            
                for (int y = 0; y < h; y++){if (src[x,y].A >= alpha_threshold){non_alpha_count++;}}
                columnNonZeroAlphas[x] = non_alpha_count ;
            }
            
            for (int x = 0 ; x < w ; x++)
            {
                ny = h - 1;
                if (columnNonZeroAlphas[x] != 0)
                {
                    N = columnNonZeroAlphas[x];
                    ty = h - N;
                    ny-=(int)(Math.Round(ty * position));
                    for (int y = h - 1 ; y >= 0 ; y--)
                    {
                        if (N != 0)
                        {
                            if (src[x,y].A >= alpha_threshold)
                            {
                                tny = influence_factor * (double)(ny) + invert_factor * (double)(y);
                                
                                if (position == 1)
                                { fy = (int)(Math.Floor(tny)) ; }
                                else
                                { fy = (int)(Math.Ceiling(tny)) ; }
                                
                                N--;
                                altsrf[x,fy] = src[x,y] ;
                                ny--;                            
                            }
                        }
                        else {break;}
                    }
                }
            }
        }
        else
        {
            for (int y = 0 ; y < h ; y++)
            {
                non_alpha_count = 0 ;            
                for (int x = 0; x < w; x++){if (src[x,y].A >= alpha_threshold){non_alpha_count++;}}
                rowNonZeroAlphas[y] = non_alpha_count ;
            }
            
            for (int y = 0 ; y < h ; y++)
            {
                nx = 0;
                if (rowNonZeroAlphas[y] != 0)
                {
                    N = rowNonZeroAlphas[y];
                    tx = w - N;
                    nx+=(int)(Math.Round(tx * position));
                    for (int x = 0 ; x < w ; x++)
                    {
                        if (N != 0)
                        {
                            if (src[x,y].A >= alpha_threshold)
                            {
                                tnx = influence_factor * (double)(nx) + invert_factor * (double)(x);
                                
                                if (position == 1)
                                { fx = (int)(Math.Ceiling(tnx)) ; }
                                else
                                { fx = (int)(Math.Floor(tnx)) ; }
                                
                                N--;
                                altsrf[fx,y] = src[x,y] ;
                                nx++;                            
                            }
                        }
                        else {break;}
                    }
                }
            }
        }
    }

     

    void Render(Surface dst, Surface src, Rectangle rect)
    {
        Rectangle selection = EnvironmentParameters.SelectionBounds;
        for (int y = rect.Top; y < rect.Bottom; y++)
        {
            if (IsCancelRequested) return;
            for (int x = rect.Left; x < rect.Right; x++)
            {
                dst[x,y] = altsrf[x,y] ;
            }
        }
    }

     

     

     

    • Like 1
  8. Just now, MJW said:

     

    Assuming dst can't be written in PreRender, you've got to figure out a way to do it in Render. It that's impossible, you need to use an auxiliary surface, do the rendering to it in PreRender, and cop the resuts to dst in Render. That's not ideal, but it's necessary for algorithms that only go in the source-to-destination direction; that is, algorithms where you can't take the destination coordinates, and figure out what color should be there.

     

    In other words, I have to start over again. Okay, I'll attempt that some time later.

  9. 6 minutes ago, MJW said:

    One thing I noticed is that in PreRender you have:

    
    dst[x,y]=ColorBgra.FromBgra(0,0,0,0);

     

    I don't think that's kosher. As far as I know, you can only write to the destination buffer in Render, and then only within the Rectangle-Of-Interest.

     

    Then, that must be part of the problem. I wanted to clear dst surface to zero as I noticed problem without doing that. The rectangle of interest is another thing that should have worked, and I checked with G'MIC-QT version of the filter, and checked the numbers of non-zero alpha between the shifted version and the non-shifted version. The expected result is exactly like the G'MIC-QT version. The code should be identical now. So, I'm lost there too.

  10. I could not get this filter to work, so I decided to dump this in this thread in case anyone wants to finish and is searching for unfinished plugin

     

     

    // Name: Axis-Based Shift Grouped Pixel to Boundary
    // Submenu: Effects / Distortion
    // Author: Reptorian
    // Title: Axis-Based Shift Grouped Pixel to Boundary
    // Version: .5
    // Desc: Incomplete filter.
    // Keywords:
    // URL:
    // Help:
    #region UICode
    DoubleSliderControl positionperc = 0; // [-100,100] Position of Pixels (%)
    DoubleSliderControl influenceperc = 100; // [0,100] Influence Factor (%)
    IntSliderControl alpha_threshold = 255; // [1,255] Alpha Threshold
    ListBoxControl axis = 1; // Axis|Horizontal|Vertical
    #endregion

    int[] rowNonZeroAlphas = null;
    int[] columnNonZeroAlphas = null;

    void PreRender(Surface dst, Surface src)
    {
        int w = src.Width, h = src.Height;
        if (rowNonZeroAlphas == null)
        {
            columnNonZeroAlphas = new int[w];
            rowNonZeroAlphas = new int[h];
            for (int x = 0; x < w; x++)
            {
                int nonZeroAlphaCount = 0;
                for (int y = 0; y < h; y++)
                {
                    if (src[x,y].A >= alpha_threshold) {nonZeroAlphaCount++;}
                    columnNonZeroAlphas[x] = nonZeroAlphaCount;
                    dst[x,y]=ColorBgra.FromBgra(0,0,0,0);
                }
            }
            for (int y = 0; y < h; y++)
            {
                int nonZeroAlphaCount = 0;
                for (int x = 0; x < w; x++)
                {
                    if (src[x,y].A >= alpha_threshold) {nonZeroAlphaCount++;}
                    rowNonZeroAlphas[y] = nonZeroAlphaCount;
                }
            }        
        }
        else
        {
            for (int x = 0; x < w; x++)
            {
                for (int y = 0; y < h; y++)
                {
                    dst[x,y]=ColorBgra.FromBgra(0,0,0,0);
                }
            }
        }
    }

    void Render(Surface dst, Surface src, Rectangle rect)
    {
        double position = (positionperc / 100 + 1) / 2;
        double influence_factor = influenceperc / 100;
        double invert_factor = 1 - influence_factor;
        int w = rect.Right;
        int h = rect.Bottom;
        int tx,ty,nx,ny,fx,fy,N;
        double tny,tnx;
        
        if (axis==1)
            {
                for (int x = 0; x < w; x++)
                {
                    if (IsCancelRequested) return;
                    ny = h - 1;
                    if (columnNonZeroAlphas[x] != 0)
                    {
                        N=columnNonZeroAlphas[x];
                        ty = h - N ;
                        ny-=(int)(ty*position);
                        for (int y = h - 1; y >= 0; y--)
                        {
                            if (N != 0)
                            {
                                if (src[x,y].A >= alpha_threshold)
                                {
                                    tny = influence_factor * (double)(ny) + invert_factor*(double)(y);
                                    if (position == 1)
                                    {
                                    fy=(int)(Math.Ceiling(tny));
                                    }
                                    else
                                    {
                                    fy=(int)(Math.Floor(tny));
                                    }
                                    N--;
                                    dst[x,fy] = src[x,y];
                                    ny--;
                               }
                            }
                            else
                            {break;}
                        }
                    }
                }
            }
        else
            {
                for (int y = 0; y < h; y++)
                {
                    if (IsCancelRequested) return;
                    nx = 0;
                    if (rowNonZeroAlphas[y] != 0)
                    {
                        N=rowNonZeroAlphas[y];
                        tx = w - N ;
                        nx+=(int)(tx*position);
                        for (int x = 0; x < w; x++)
                        {
                            if (N != 0)
                            {
                                if (src[x,y].A >= alpha_threshold)
                                {
                                    tnx = influence_factor * (double)(nx) + invert_factor*(double)(x);
                                    if (position == 0)
                                    {
                                    fx=(int)(Math.Ceiling(tnx));
                                    }
                                    else
                                    {
                                    fx=(int)(Math.Floor(tnx));
                                    }
                                    N--;
                                    dst[fx,y] = src[x,y];
                                    nx++;
                               }
                            }
                            else
                            {break;}
                        }
                    }
                }
            }
    }

     

     

  11. It's coming along!

     

     

    // Name: Shifted Group Pixel to Boundary
    // Submenu:
    // Author:
    // Title:
    // Version:
    // Desc:
    // Keywords:
    // URL:
    // Help:
    #region UICode
    DoubleSliderControl positionperc = -100; // [-100,100] Position of Pixels (%)
    DoubleSliderControl influenceperc = 100; // [0,100] Influence Factor (%)
    IntSliderControl alpha_threshold = 255; // [1,255] Alpha Threshold
    ListBoxControl axis = 1; // Axis|Horizontal|Vertical
    #endregion

    void Render(Surface dst, Surface src, Rectangle rect)
    {
        double position = (positionperc / 100 + 1) / 2;
        double influence_factor = influenceperc / 100;
        double invert_factor = 1 - influence_factor;
        int w = rect.Right;
        int h = rect.Bottom;
        int tx,ty,nx,ny,fx,fy,N;
        double tny,tnx;
        
        int[] columnNonZeroAlphas = new int[w];
        int[] rowNonZeroAlphas = new int[h];
        
        if (axis==1)
        {
            for (int x = 0; x < w; x++)
            {
                int nonZeroAlphaCount = 0;
                for (int y = 0; y < h; y++)
                {
                    if (src[x,y].A >= alpha_threshold) {nonZeroAlphaCount++;}
                    columnNonZeroAlphas[x] = nonZeroAlphaCount;
                    dst[x,y]=ColorBgra.FromBgra(0,0,0,0);
                }
            }
        }
        else
        {
            for (int y = 0; y < h; y++)
            {
                int nonZeroAlphaCount = 0;
                for (int x = 0; x < w; x++)
                {
                    if (src[x,y].A >= alpha_threshold) {nonZeroAlphaCount++;}
                    rowNonZeroAlphas[y] = nonZeroAlphaCount;
                    dst[x,y]=ColorBgra.FromBgra(0,0,0,0);
                }
            }
        }

        if (axis==1)
            {
                for (int x = 0; x < w; x++)
                {
                    if (IsCancelRequested) return;
                    ny = h - 1;
                    if (columnNonZeroAlphas[x] != 0)
                    {
                        N=columnNonZeroAlphas[x];
                        ty = h - N ;
                        ny-=(int)(ty*position);
                        for (int y = h - 1; y >= 0; y--)
                        {
                            if (N != 0)
                            {
                                if (src[x,y].A >= alpha_threshold)
                                {
                                    tny = influence_factor * (double)(ny) + invert_factor*(double)(y);
                                    if (position == 1)
                                    {
                                    fy=(int)(Math.Ceiling(tny));
                                    }
                                    else
                                    {
                                    fy=(int)(Math.Floor(tny));
                                    }
                                    N--;
                                    dst[x,fy] = src[x,y];
                                    ny--;
                               }
                            }
                            else
                            {break;}
                        }
                    }
                }
            }
        else
            {
                for (int y = rect.Top; y < rect.Bottom; y++)
                {
                    if (IsCancelRequested) return;
                    nx = 0;
                    if (rowNonZeroAlphas[y] != 0)
                    {
                        N=rowNonZeroAlphas[y];
                        tx = w - N;
                        nx+=(int)(tx*(position));
                        for (int x = 0; x < rect.Right; x++)
                        {
                            if (N != 0)
                            {
                                if (src[x,y].A >= alpha_threshold)
                                {
                                    tnx = influence_factor * (double)(nx) + invert_factor*(double)(x);
                                    if (position == 1)
                                    {
                                    fx=(int)(Math.Floor(tnx));
                                    }
                                    else
                                    {
                                    fx=(int)(Math.Ceiling(tnx));
                                    }
                                    N--;
                                    dst[fx,y] = src[x,y];
                                    nx++;
                                }
                            }
                            else
                            {break;}
                        }
                    }
                }
            }
    }

     

  12. Um, I am getting a error here. Otherwise, code looks pretty much correct if you look at the reference code.

     

    EDIT: I am getting it to work it seems, just very buggy. :(

     

     

    // Name: Shifted Group Pixel to Boundary
    // Submenu:
    // Author:
    // Title:
    // Version:
    // Desc:
    // Keywords:
    // URL:
    // Help:
    #region UICode
    DoubleSliderControl positionperc = -100; // [-100,100] Position of Pixels (%)
    DoubleSliderControl influenceperc = 100; // [0,100] Influence Factor (%)
    IntSliderControl alpha_threshold = 1; // [1,255] Alpha Threshold
    ListBoxControl axis = 0; // Axis|Horizontal|Vertical
    #endregion

    int[] columnNonZeroAlphas = null;
    int[] rowNonZeroAlphas = null;

    void PreRender(Surface src)
    {
        int width = src.Width, height = src.Height;
        if (rowNonZeroAlphas == null)
        {
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                   if (src[x,y].A >= alpha_threshold)
                   {
                            columnNonZeroAlphas[x]++;
                            rowNonZeroAlphas[y]++;    
                   }
                }
            }
        }
    }


    void Render(Surface dst, Surface src, Rectangle rect)
    {
        double position = (positionperc / 100 + 1) / 2;
        double influence_factor = influenceperc / 100;
        double invert_factor = 1 - influence_factor;
        int width = rect.Right;
        int height = rect.Bottom;
        int txx,tyy,nxx,nyy,fx,fy,N;
        double tnyy,tnxx;

        if (axis==0)
            {
                for (int x = 0; x < rect.Right; x++)
                {
                    nyy = height - 1;
                    if (columnNonZeroAlphas[x] != 0)
                    {
                        N=columnNonZeroAlphas[x];
                        tyy = height - N ;
                        nyy-=(int)(tyy*position);
                        for (int y = height - 1; y > - 1; y++)
                        {
                            if (N != 0)
                            {
                                if (src[x,y].A >= alpha_threshold)
                                {
                                    N--;
                                    tnyy = influence_factor * (double)(nyy) + invert_factor*(double)(y);
                                    if (position == 1)
                                    {
                                        fy=(int)(Math.Ceiling(tnyy));
                                    }
                                    else
                                    {
                                        fy=(int)(Math.Floor(tnyy));
                                    }
                                    dst[x,y] = src[x,fy];
                                    nyy--;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }
            }
        else
            {
                for (int y = rect.Top; y < rect.Bottom; y++)
                {
                    nxx = 0;
                    if (rowNonZeroAlphas[y] != 0)
                    {
                        N=rowNonZeroAlphas[y];
                        txx = width - N;
                        nxx+=(int)(txx*(position));
                        for (int x = 0; x < rect.Right; x++)
                        {
                            if (N != 0)
                            {
                                if (src[x,y].A >= alpha_threshold)
                                {
                                    N--;
                                    tnxx = influence_factor * (double)(nxx) + invert_factor*(double)(x);
                                    if (position == 1)
                                    {
                                        fx=(int)(Math.Floor(tnxx));
                                    }
                                    else
                                    {
                                        fx=(int)(Math.Ceiling(tnxx));
                                    }
                                    dst[x,y] = src[fx,y];
                                    nxx++;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }
            }
    }

  13. 2 hours ago, Foxxey said:

    @Reptilliani tried to install ur plugin in G'MIC in Paint.net, but it didnt work. I am new to G'MIC. What did I do wrong?

    Screenshot_75.png

     

    You're supposed to update via the arrow next to the checkmark and internet within the GUI plugin which is under Advanced->G'MIC-QT. If the filter I have made does not show up within 2.9.0, that means it's no longer supported hence why I said if you have access to G'MIC-QT 2.9.1 which as of now are only available as a plugin for GIMP, Krita. 2.9.1 is right around the corner as it's getting closer to completion, so you will have access to this via Paint.NET very soon if it is not available for 2.9.0.

     

    My g'mic-qt filters are under Testing->Reptorian.

  14. 3 hours ago, Foxxey said:

    Please code the plugin with Codelab and send me the script, I want to use it for my other plugin. imma credit you.

     

    Um, that's not how it works. If someone feel like doing this, then they'll do it. However, I think this is a rather interesting idea. I know how to replicate it via g'mic-qt though that's not what you want and it's very easy for me to do this. I could modify this code of mine and insert it as a new filter.

     

    For reference:

     

     

    #@cli rep_pstrk: eq. to 'rep_perspective_streak' : (+)
    rep_pstrk: rep_perspective_streak $*
    #@cli rep_perspective_streak: -1<=_xpos<=1,-1<=_ypos<=1,-1<=_alpha_exponential_factor,0<_distance_threshold<=1,0<_distance_start<=1,_direction={ 0=in | 1=out },_streak_mode={ 0=color | 1=gray | 2=binary | 3=gray+binary },_preserve_edges={ 0=do_not_preserve_edges | 1=preserve_edges }
    #@cli : Create perspective streak effect. _preserve_details only is applicable on non-binary mode.
    #@cli : (eq. to 'rep_pstrk').\n
    #@cli : Default values: '_xpos=0','_ypos=0','_alpha_exponential_factor=1','_distance_threshold=1','_distance_start=0','_direction=0','_streak_mode=0','_preserve_edges=1'
    rep_perspective_streak:
    skip ${1=0},${2=0},${3=0},${4=1},${5=0},${6=0},${7=0},${8=1}
    point={[$1,$2]}
    if !$4 error "$4|"$"4>0" fi
    repeat $! l[$>]
        if s!=3
            echo "Applying perspective streak at coordinate point $point!"
            if h>w orientation=1
            else orientation=0
            fi
            if s>1
                sh. 0,{s-2}
                +channels.. {s#0-1}
                f. i==0?1:0
                inpaint_pde.. .
                rm[-2,-1]
            fi
            rep_recpoltrans $point,-3
                if $5>0&&$5<1 f begin(sy=1/(((1-$5)*h)/h););i(x,y*sy,z,c,2); fi
                if $7||s==1
                    channels {s-1}
                    if $8
                        if $7==3||$7==1 . n. 0,1 l. +f 1 rv a c endl store. details
                        else echo "Details cannot be preserved using binary mode!"
                        fi
                    fi
                    rep_axis_streak 1,!$6,$3
                    if $4>0&&$4<1
                        f i>(1-$4)?i:(1-$4)
                        n 0,1
                    fi
                    if $7==2 f i>0?1:0
                    elif $7==3 +f i>0?1:0 a c fi
                    if $8
                        if $7==3||$7==1
                            $details
                            s. c,-{s-1}
                            j[-3] [-2],0,0,0,0,1,[-1],1
                            rm[-2,-1]
                        fi
                    fi
                else
                    if $8 +store details fi
                    if $4>0&&$4<1
                        +channels {s-1}
                        rep_axis_streak. 1,!$6,$3
                        f. i>(1-$4)?i:(1-$4)
                        f. i>im#-1?1:0
                    fi
                    rep_axis_streak[0] 1,!$6,$3
                    if $4>0&&$4<1
                        sh[0] {s#0-1}
                        f. i0#-2*i
                        k[0]
                    fi
                    if $8
                        $details
                        s. c,-{s-1}
                        j[-3] [-2],0,0,0,0,1,[-1],{iM#-1}
                        rm[-2,-1]
                    fi
                fi
            rep_recpoltrans $point,2,$orientation
        else echo "Not applicable to images with 3 channels!"
        fi
    endl done

     

     

    Between rep_recpoltrans I can modify the code to use rep_sptbwgp which is my extended version of MadJik's Gravity plugin. After that it's erasing irrelevant line. It's easy for me to do something like this.

     

    Also, for more information on rep_recpoltrans (the code there is outdated though as I have made better implementation with the reverse transformation as well) - https://discuss.pixls.us/t/geometry-help-rectangular-polar-transformation-from-cartesian-or-to-cartesian-solved-or-nearly-solved/15060

     

    I hope I provided enough information on how your plugin would probably work like.

  15. 2 hours ago, MJW said:

    If you need the info for both the rows and columns, the simplest way is probably:

    
    		for (int y = 0; y < height; y++)
    		{
    			for (int x = 0; x < width; x++)
    			{
    				if (src[x, y].Alpha != 0)
    				{
    					columnNonZeroAlphas[x]++;
    					rowNonZeroAlphas[y]++;	
    				}
    			}
    		}

    There are probably slightly more efficient ways, but since it only runs once, and doesn't do anything too complex, it's probably plenty efficient enough.

     

    (You don't need to first zero the arrays, since C# zeroes numeric arrays when they're allocated.)

     

    The columnnonzeroalpha[x]++ is something I would have never thought off for generic scripting/programming. Thank you.

  16. 5 minutes ago, MJW said:

    If I correctly understand the question (which I may not), you would just count and save the number of pixels with non-zero alphas in each row or column in the pre-processing step, which is PreRender() in Codelab and OnSetRenderInfo() in Visual Studio. Since it doesn't change, a flag (likely just the non-null pointer to the array where the results are saved) should be used to prevent re-doing it each time a control is changed.

     

    Most of that I get, but I would like the fastest way to create a vector of non-zero alpha counts. I suppose there's either do while or for loop method.

     

    You lost me at flag though. Explain.

×
×
  • Create New...