Reptillian Posted March 14, 2020 Share Posted March 14, 2020 (edited) Inspired by @ReMake, I have decided to take my version which contains more variety. (Two different source codes for this is provided below. C# and G'MIC-QT). All this filter does is to interpolate between rgb and grayscale value. Download - RGB to Linear Interpolation.dll It's under Effects/Colors ------ License - CeCiLLv2.0 - https://cecill.info/licences/Licence_CeCILL_V2-en.html Source code in C# // Name: RGB-Gray Linear Interpolation // Submenu: Effects\Colors // Author: Reptorian // Title: RGB to Gray Linear Interpolation // Version: 1.0 // Desc: Interpolate between rgb value and grayscale value // Keywords: interpolation,adjustment // URL: forums.getpaint.net // Help: #region UICode ListBoxControl Mode = 1; // GrayMode|Weighted|Luminosity A|Luminosity B|HSL Lightness|Minimum Channel|Maximum Channel|Average IntSliderControl RedFactor = 255; // [0,360] Red Factor IntSliderControl GreenFactor = 255; // [0,360] Green Factor IntSliderControl BlueFactor = 255; // [0,360] Blue Factor DoubleSliderControl RedWeight = 1; // [0,1] {Mode} Red Weight DoubleSliderControl GreenWeight = 1; // [0,1] {Mode} Green Weight DoubleSliderControl BlueWeight = 1; // [0,1] {Mode} Blue Weight #endregion private int Weighted(int rval,int gval, int bval, double rw, double gw, double bw) { double rfactor=(double)(rw*rval); double gfactor=(double)(gw*gval); double bfactor=(double)(bw*bval); double endval=rfactor+gfactor+bfactor; return (int)(endval); } private int Luma_A(int rval,int gval, int bval) { double rfactor=(double)(0.22248840*rval); double gfactor=(double)(0.71690369*gval); double bfactor=(double)(0.06060791*bval); double endval=rfactor+gfactor+bfactor; return (int)(endval); } private int Luma_B(int rval,int gval, int bval) { double rfactor=(double)(0.2989*rval); double gfactor=(double)(0.5870*gval); double bfactor=(double)(0.1140*bval); double endval=rfactor+gfactor+bfactor; return (int)(endval); } private int lightness(int rval,int gval, int bval) { int max_factor=Math.Max(Math.Max(rval,gval),Math.Max(gval,bval)); int min_factor=Math.Min(Math.Min(rval,gval),Math.Min(gval,bval)); double grayval=(double)((max_factor+min_factor)/2); return (int)(grayval); } private int max(int rval,int gval, int bval) { return Math.Max(Math.Max(rval,gval),Math.Max(gval,bval)); } private int min(int rval,int gval, int bval) { return Math.Min(Math.Min(rval,gval),Math.Min(gval,bval)); } private int average(int rval,int gval, int bval) { double avg = (double)((rval+gval+bval)/3); return (int)(avg); } private ColorBgra Interpolation(int rval,int gval,int bval,int rlvl,int glvl,int blvl,int gray,int A) { int rr = (rval * rlvl + gray * (255 - rlvl)) / 255; int gg = (gval * glvl + gray * (255 - glvl)) / 255; int bb = (bval * blvl + gray * (255 - blvl)) / 255; return ColorBgra.FromBgraClamped(bb,gg,rr,A); } void Render(Surface dst, Surface src, Rectangle rect) { // Delete any of these lines you don't need Rectangle selection = EnvironmentParameters.SelectionBounds; int Gray=0; double totalweight=RedWeight+GreenWeight+BlueWeight; double red_weight=RedWeight/totalweight; double green_weight=GreenWeight/totalweight; double blue_weight=BlueWeight/totalweight; 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); int A=(int)(CurrentPixel.A); switch (Mode) { case 0: Gray = Weighted(R,G,B,red_weight,green_weight,blue_weight); break; case 1: Gray = Luma_A(R,G,B); break; case 2: Gray = Luma_B(R,G,B); break; case 3: Gray = lightness(R,G,B); break; case 4: Gray = min(R,G,B); break; case 5: Gray = max(R,G,B); break; case 6: Gray = average(R,G,B); break; } ColorBgra Final=Interpolation(R,G,B,RedFactor,GreenFactor,BlueFactor,Gray,A); dst[x,y] = Final; } } } Source Code in G'MIC-QT #@cli rep_lerp_rgb_gray: eq. to rep_linear_interpolation_rgb_gray : (+) rep_lerp_rgb_gray: rep_linear_interpolation_rgb_gray $* #@cli rep_linear_interpolation_rgb_gray: 0%>=_red_factor(%)<=100%,0%>=_green_factor(%)<=100%,0%>=_blue_factor(%)<=100%,_gray_mode={ 0=luminosity | 1=luminosity_alternative | 2=lightness | 3=minimum_channel | 4=maximum_channel | 5=average } : 0%>=_red_factor(%)<=100%,0%>=_green_factor(%)<=100%,0%>=_blue_factor(%)<=100%,_red_weight,green_weight,blue_weight rep_linear_interpolation_rgb_gray: skip ${4=0},${5=},${6=} total_arg=0 if isnum($1) total_arg+=1 fi if isnum($2) total_arg+=1 fi if isnum($3) total_arg+=1 fi if isnum($4) total_arg+=1 fi if isnum($5) total_arg+=1 fi if isnum($6) total_arg+=1 fi if $total_arg==5 error "narg!=5=F" fi if abs($1)>2 error "|"$"1|<=2=F" fi if abs($2)>2 error "|"$"2|<=2=F" fi if abs($3)>2 error "|"$"3|<=2=F" fi f " begin( rlvl=abs($1); glvl=abs($2); blvl=abs($3); if(narg($*)>5, tw=abs($4)+abs($5)+abs($6); c1f=abs($4)/tw; c2f=abs($5)/tw; c3f=abs($6)/tw; graymode(a,b,c)=a*c1f+b*c2f+c*c3f; , if($4==0,graymode(a,b,c)=a*0.22248840+b*0.71690369+c*0.06060791;, if($4==1,graymode(a,b,c)=a*0.2989+b*0.5870+c*0.1140;, if($4==2,graymode(a,b,c)=(max(a,b,c)+min(a,b,c))/2;, if($4==3,graymode(a,b,c)=min(a,b,c);, if($4==4,graymode(a,b,c)=max(a,b,c);, graymode(a,b,c)=avg(a,b,c); ); ); ); ); ); ); ); gl=graymode(i0,i1,i2); [lerp(gl,i0,rlvl),lerp(gl,i1,glvl),lerp(gl,i2,blvl)] " #@gui RGB-Gray Linear Interpolation: fx_rep_lerp_rgb_gray,fx_rep_lerp_rgb_gray_preview(0) #@gui : _=note("<b>Formula</b>") #@gui : Mode=choice(0,"Luminosity A","Luminosity B","Lightness","Minimum","Maximum","Average",Weighted") #@gui : Limit Factor to 100%=bool(0) #@gui : sep=separator(),_=note("<b>Channel Factor</b>") #@gui : Red Factor (%)=float(100,0,150) #@gui : Green Factor (%)=float(100,0,150) #@gui : Blue Factor (%)=float(100,0,150) #@gui : Red Factor (%)=float(100,0,100) #@gui : Green Factor (%)=float(100,0,100) #@gui : Blue Factor (%)=float(100,0,100) #@gui : Red Weight=float(1,0,1) #@gui : Green Weight=float(100,0,1) #@gui : Blue Weight=float(100,0,1) #@gui : sep=separator(),_=note("<b>Preview</b>"),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>2020/14/3</i>.</small>") fx_rep_lerp_rgb_gray: if $1==6 if $2 rep_lerp_rgb_gray $6%,$7%,$8%,${9-11} else rep_lerp_rgb_gray $3%,$4%,$5%,${9-11} fi else if $2 rep_lerp_rgb_gray $6%,$7%,$8%,$1 else rep_lerp_rgb_gray $3%,$4%,$5%,$1 fi fi fx_rep_lerp_rgb_gray_preview: gui_split_preview "fx_rep_lerp_rgb_gray ${1-11}",${-3--1} u "{$1}"\ "{$2}"\ "{$3}_"{$2?0:2}\ "{$4}_"{$2?0:2}\ "{$5}_"{$2?0:2}\ "{$6}_"{$2?2:0}\ "{$7}_"{$2?2:0}\ "{$8}_"{$2?2:0}\ "{$9}_"{$1==6?2:0}\ "{$10}_"{$1==6?2:0}\ "{$11}_"{$1==6?2:0}\ "{$12}"\ "{$13,14}" Edited May 19, 2020 by Reptillian Typos elimination again... 2 1 Quote G'MIC Filter Developer Link to comment Share on other sites More sharing options...
ReMake Posted March 14, 2020 Share Posted March 14, 2020 Some comments and suggestions: Your code does not save transparent areas of the image by replacing them with white. To fix this, add int A = CurrentPixel.A; under int B = CurrentPixel.B; Add int A after the gray variable in Interpolation() private ColorBgra Interpolation(int rval, int gval, int bval, int rlvl, int glvl, int blvl, int gray, int A) and add A to ColorBgra Final ColorBgra Final = Interpolation(R, G, B, RedFactor, GreenFactor, BlueFactor, Gray, A); The code snippet if(rr>255){rr=255;} if(rr<0){rr=0;} if(gg>255){gg=255;} if(gg<0){gg=0;} if(bb>255){bb=255;} if(bb<0){bb=0;} return ColorBgra.FromBgr((byte)(bb),(byte)(gg),(byte)(rr)); can be deleted and replaced with line return ColorBgra.FromBgraClamped(bb, gg, rr, A); In Luma_A () and Luma_B () in the lines double bfactor=(double)(0.06060791*gval); and double bfactor=(double) (0.1140*gval); probably a typo (gval or bval)? Interesting effect in any case. 2 Quote Link to comment Share on other sites More sharing options...
Reptillian Posted March 14, 2020 Author Share Posted March 14, 2020 All typos fixed and added alpha support. Thanks, Remake. Quote G'MIC Filter Developer Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.