View Single Post
Old 15th April 2017, 07:58   #4  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Elliptical_Marker.avs. Probably complete.
Code:
# Elliptical_Marker.avs

Function Elliptical_Marker(int w,Int h,
        \ Float "iRad",
        \ Float "oSoft",Int "oFI",Int "oFO",
        \ Float "iSoft",Int "iFI",Int "iFO",
        \ Int "cInt",Int "cExt",Int "cHub",Int "cPad",
        \ Bool "YV12",Bool "Mod2") {
/*
    Elliptical_Marker by StainlessS.  http://forum.doom9.org/showthread.php?t=174527

    Req mt_tools2, RT_Stats.    
    Creates an Elliptical marker mask WxH, for use with Overlay as Mask arg.
    Returns single frame clip with null audio, the marker top left hand side is aligned to 0,0, and is contained in the area WxH.
    The Default return clip colorspace is Y8 for Avisynth v2.6 and above, or YV12 if defunct version.
    
      The Elliptical mask radius described below is normalised to 1.0, no matter whether WxH is square or not.
    A radius of 1.0 lies on the outer edge of the elliptical mask, and the origin at mask center (center of WxH).
    The Mask is optionally a Disk(iRad=0.0) or Ring(0.0<iRad), and optional softening/feathering of outer and inner edges.
    A Ring mask (0.0 < iRad), has a Hub (hollow bit in the middle), and inner softening is applied from the inside edge of the Ring(iRad).
    A Disk Mask (0.0 = iRad), has no Hub, and inner softening is again applied from iRad outwards but in this case iRad=0.0 ie the origin.
    The 'Thickness' of a Ring/Disk is 1.0 - iRad, so for a Disk, it is always 1.0.
    oSoft and iSoft control softening of the mask Thickness, eg oSoft=0.2 and iSoft=0.1, applies softening to the outermost 0.2
    and innermost 0.1 of the ThickNess. The part of the Thickness that is not softened, we will call the 'Interior', and in this case 
    would be the distance bewteen 0.1 and 1.0-0.2, ie 0.7 of the ThickNess.
    In a case where iSoft and oSoft sum to more than 1.0, they will both self scale so that they sum to 1.0. 
    Where:- sumSoft=oSoft+iSoft, and where 1.0 < sumSoft then. 
      oSoft=oSoft/sumSoft, iSoft=iSoft/sumSoft
    So, if eg iSoft=0.5 and oSoft=1.0 they will scaled to iSoft=0.333, oSoft = 0.666 and so inner and outer softening will meet 
    0.333 from inner ring edge, or 0.666 from outer edge. Where oSoft and iSoft sum to 1.0 or more, Interior will be 0.0.                                   
    The part of a mask that lies more than 1.0 distant from the origin, we will call the 'Exterior", ie outside of the Ellipse.
    The part of a frame that lies outside of WxH, we will call 'Padding", and will only exist if W or H was odd, and either 
    return frame is YV12, or Mod2 is true, it is NOT part of a mask.
    NOTE, For an Overlay mask, The nearer to 255 the mask, the more opaque the overlayed clip, the nearer to 0, the more transparent. 
          
    w,h,   Size of marker mask (can be odd), return clip dimensions are rounded up to next multiple of 2 if YV12 or Mod2 return clip.
    iRad,  Default 0.0(Disk). 0.0 <= iRad < 1.0. If 0.0 < iRad, then is a Ring Mask with a central 'hollow' region or hub.
             If iRad=0.0, then is a Disk Mask and arg cHub has NO FUNCTION AT ALL (there is no Hub).      
             iRad is the Inner radius, distance from center or origin to inside of the Ring, an iRad of 0.5 would
             create a Ring Mask with a central hollow hub mid way between origin and the ellipse edge at radius of 1.0.
             The outer 'ThickNess' of the ring is therefore 1.0-iRad.     
    oSoft, Default 0.0. 0.0 <= oSoft : 0.0 = No outer softening. (Hard Outer Edge)
             If oSoft is greater than 0.0, then applies softening/feathering to the outer edge of the ellipse Thickness.
             For a disk (where iRad=0.0), an oSoft of 1.0 applies softening all of the way to the center or origin of the disk.
             oSoft controls the distance from ellipse edge, with 1.0 being the radius of the disk, 0.1 would soften just the
             outer 0.1 of the Thickness of the disk.
    oFI,   Default 255. 0 -> 255. Outer edge, Innermost softening value.
    oFO,   Default 0.   0 -> 255. Outer edge, Outermost softening value.                 
             The outer edge of Thickness is softened by interpolating linearly between these two values.
    iSoft, Default 0.0. 0.0 <= iSoft : 0.0 = No inner softening. (If Ring, Hard inner Edge)
             If iSoft is greater than 0.0, then applies softening/feathering to the inner Thickness.
             For a disk (where iRad=0.0), an iSoft of 1.0 applies softening all of the way to outer edge of the disk.
    iFI,   Default 0.   0 -> 255. Inner edge, Innermost softening value.
    iFO,   Default 255. 0 -> 255. Inner edge, Outermost softening value.                 
             The inner edge of Thickness is softened by interpolating linearly between these two values.
    cInt,  Default 255, Color of non softened or Interior of mask (mask inspection/special effect).
    cExt,  Default 0,   Color of 'invald' mask, Exterior to Ellipse, (mask inspection/special effect).
    cHub,  Default 0,   Color of 'invald' mask, Ring hollow center, (mask inspection/special effect).
    cPad,  Default 0,   Color of extra padding where odd dimensions and YV12, ie not part of mask. (usually not changed, mask inspection).    
    YV12,  Default False if Avisynth version 2.6 or greater(Y8), else true(YV12). Selects return clip colorspace.
    Mod2,  Default True. If Y8 then round odd dimensions up modulo 2 (the mask is still WxH with possible padding).    
    Example:-
        Import("Elliptical_marker.avs")
        WW=320  HH=320  iRad=0.5 oSoft=0.5  iSoft=0.5  
        BlankClip.KillAudio
        Sym=Colorbars.BicubicResize(WW,HH).KillAudio
        msk=Elliptical_Marker(sym.width,sym.height,iRad=iRad,oSoft=oSoft,iSoft=iSoft)
        OverLay(Last,Sym,x=(width-Sym.width)/2,y=(height-Sym.height)/2,mask=msk)
*/    
    myName="Elliptical_Marker: "
    iRad=Default(iRad,0.0)          # 0.0 < iRad then Ring, else disk
    oSoft=Default(oSoft,0.0)        # Outer softening distance
    oFI=Default(oFI,255)            # Outer edge, Innermost softening value.
    oFO=Default(oFO,0)              # Outer edge, Outermost softening value. 
    iSoft=Default(iSoft,0.0)        # Inner softening distance
    iFI=Default(iFI,0)              # Inner edge, Innermost softening value.
    iFO=Default(iFO,255)            # Inner edge, Outermost softening value.
    cInt=Default(cInt,255)          # Interior Color (mask color, white)
    cExt=Default(cExt,0)            # Exterior to ellipse (Invalid black) color
    cHub=Default(cHub,0)            # Ring Hub (Invalid black) color
    cPad=Default(cPad,0)            # Padding color (not part of mask, black)
    is26=VersionNumber>=2.6         YV12=(!is26) ?True:Default(YV12,False)  Mod2=Default(Mod2,True)     Mod=(YV12||Mod2) ?2:1   
    CanvasW=(w+Mod-1)/Mod*Mod       CanvasH=(h+Mod-1)/Mod*Mod
    Assert(0.0 <= iRad < 1.0,RT_String("%s0.0 <= iRad < 1.0 (%f)",myName,iRad))
    Assert(0.0 <= oSoft,RT_String("%s0.0 <= oSoft (%f)",myName,oSoft))
    Assert(0.0 <= iSoft,RT_String("%s0.0 <= iSoft (%f)",myName,iSoft))
    SoftSum=oSoft+iSoft  oSoft=(SoftSum>1.0)?oSoft/SoftSum:oSoft  iSoft=(SoftSum>1.0)?1.0-oSoft:iSoft
    Thick=1.0-iRad       oRim=1.0-Thick*oSoft                     iRim=iRad+Thick*iSoft   
    wMid = (w-1)/2.0     wMul = 2.0/w      hMid = (h-1)/2.0       hMul = 2.0/h
    oFade = 255 / Max(1.0-oRim,0.001)      iFade = 255 / Max(iRim-iRad,0.001)
    ###
    # Normalizing H and V distances 0.0->1.0. (irrespective of elliptical squishing)          
    # We dont use mt_lutspa(relative=true) due to padding complications.
    # Dist from center origin, 0->1.0, by Pythagoras (1.0 is placed 1/2 pixel outside of ellipse [outside of WxH])
    # DIST = "(((((x-wMid)*wMul)^2) + (((y-hMid)*hMul)^2))^.5)"
    # OMELT="((1.0-DIST)*oFade)"       IMELT="((DIST-iRad)*iFade)"                   
    # OZ="((((256-OMELT)*oFO) + (OMELT*oFI) + 128) / 256.)"
    # IZ="((((256-IMELT)*iFI) + (IMELT*iFO) + 128) / 256.)"                   
    # CHK="(x>=WW|y>=HH)"   # Padding area check.
    # InFix="CHK ? cPad :(DIST >= 1. ? cExt :(DIST < iRad ? cHub :((DIST <= iRim) ? IZ :(DIST < oRim ? cInt : OZ))))"
    ###
    Rpn= "x WW >= y HH >= | 0 x wMid - wMul * 2 ^ y hMid - hMul * 2 ^ + .5 ^ 1. >= cExt x wMid - wMul * 2 ^ y hMid - hMul " +
        \ "* 2 ^ + .5 ^ iRad < cHub x wMid - wMul * 2 ^ y hMid - hMul * 2 ^ + .5 ^ iRim <= 256 x wMid - wMul * 2 ^ y hMid " +
        \ "- hMul * 2 ^ + .5 ^ iRad - iFade * - iFI * x wMid - wMul * 2 ^ y hMid - hMul * 2 ^ + .5 ^ iRad - iFade * iFO * " +
        \ "+ 128 + 256. / x wMid - wMul * 2 ^ y hMid - hMul * 2 ^ + .5 ^ oRim < cInt 256 1. x wMid - wMul * 2 ^ y hMid - "  +
        \ "hMul * 2 ^ + .5 ^ - oFade * - oFO * 1. x wMid - wMul * 2 ^ y hMid - hMul * 2 ^ + .5 ^ - oFade * oFI * + 128 + "  +
        \ "256. / ? ? ? ? ?"    
    Fnd=RT_String("oFade\niFade\nwMid\nwMul\nhMid\nhMul\noRim\niRim\niRad\nWW\nHH\ncInt\ncExt\ncHub\ncPad\noFI\noFO\niFI\niFO\n")
    Rep=RT_String("%f\n%f\n%f\n%f\n%f\n%f\n%f\n%f\n%f\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n",
        \ oFade,iFade,wMid,wMul,hMid,hMul,oRim,iRim,iRad,W,H,cInt,cExt,cHub,cPad,oFI,oFO,iFI,iFO)
    Rpn=RT_StrReplaceMulti(Rpn,Fnd,Rep)
    Blankclip(width=CanvasW,height=CanvasH,Length=1,pixel_type=YV12?"YV12":"Y8").Killaudio
    Last.mt_lutspa(relative=false,Yexpr=RPN, chroma = "-128" )
    return Last
}
We see Distance 1.0 as outside of ellipse, to avoid single pixel spike (nobble) every 90 degrees from 12 O-Clock.
Update, now native RPN, works on XP without latest version MaskTools Infix -> RPN conversion (mt_Polish dont work for XP).
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 2nd May 2017 at 22:16. Reason: Updated
StainlessS is offline   Reply With Quote