Public/Get-GradientColor.ps1

function Get-GradientColor {
    <#
    .SYNOPSIS
    Returns the colors of a gradient: one for each of a number of characters, or the color at each
    of several places along it.
 
    .DESCRIPTION
    Get-GradientColor blends a gradient as Write-ColorEX's -Gradient does and returns its colors as
    RGB arrays, three values from 0 to 255 in each, the form -Color and -Gradient take.
 
    -Count returns the colors of that many characters, as Write-ColorEX draws the gradient across a
    line of that length. -Place returns the color at each place given along the gradient, from 0 at
    its start to 1 at its end, in the order given, for a single color that moves along it; colors
    placed with '@' keep their exact places, since there are no characters to move them to.
 
    .PARAMETER Gradient
    Two or more colors, or the name of a named gradient, as Write-ColorEX's -Gradient takes them. A
    color may give its place along the gradient after an '@', as a percent: 'Gold@40'.
 
    .PARAMETER Count
    The number of colors to return, as for a line of that many characters.
 
    .PARAMETER Place
    The places along the gradient of the colors to return, from 0 at its start to 1 at its end: one
    color for each place, in the order given. A place below 0 is 0 and above 1 is 1.
 
    .PARAMETER GradientSpace
    How the colors blend: OKLab (the default), RGB, LinearRGB, OKLCH, HSL, HSV, Lab or LCh, as
    Write-ColorEX's -GradientSpace takes them.
 
    .PARAMETER GradientHue
    The way round the hue wheel in OKLCH, HSL, HSV and LCh: Shorter (the default), Longer,
    Increasing or Decreasing.
 
    .PARAMETER GradientEasing
    A curve that moves the colors along the gradient, as Write-ColorEX's -GradientEasing takes it.
 
    .PARAMETER GradientRepeat
    What the gradient does past placed first and last colors: None (the default), Repeat or Mirror.
 
    .PARAMETER GradientDirection
    The way the gradient runs: Forward (the default), Reverse, CenterOut or EdgesIn.
 
    .PARAMETER GradientSteps
    Cuts the gradient into this many bands of solid color; 0, the default, blends smoothly.
 
    .INPUTS
    None
 
    .OUTPUTS
    System.Int32[]
    One RGB array for each color.
 
    .EXAMPLE
    Get-GradientColor -Gradient Red, Blue -Count 5
 
    The five colors Write-ColorEX -Gradient Red, Blue draws across five characters.
 
    .EXAMPLE
    Get-GradientColor -Gradient Progress -Place 0.75
 
    The color three quarters of the way along the Progress gradient.
 
    .EXAMPLE
    Get-GradientColor -Gradient Progress -Place (0..100 | ForEach-Object { $_ / 100 })
 
    The Progress gradient's color at each whole percent, 101 colors from one call.
 
    .EXAMPLE
    $colors = Get-GradientColor -Gradient Sunset -Count 3 -GradientSpace OKLCH
    Write-ColorEX -Text 'one ', 'two ', 'three' -Color $colors
 
    Writes each word in one of three colors from the Sunset gradient, blended in OKLCH.
 
    .NOTES
    Author: Mark Newton
    License: MIT
    Requires: PowerShell 5.1 or later
 
    A color name the color table lacks gives a warning and blends as gray.
 
    .LINK
    https://github.com/MarkusMcNugen/PSWriteColorEX
 
    .LINK
    Write-ColorEX
    #>

    [CmdletBinding(DefaultParameterSetName = 'Count')]
    [Alias('Get-GradientColour')]
    [OutputType([int[]])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', 'unknownColorNames', Justification = 'The helpers in Private/WriteColorCore.ps1 that this function calls read it through PowerShell''s dynamic scope.')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '', Justification = 'The comma writes each Int32[] to the pipeline whole; the analyzer reads the comma''s own array type.')]
    param(
        [Parameter(Mandatory, Position = 0)]
        [object[]] $Gradient,

        [Parameter(Mandatory, ParameterSetName = 'Count')]
        [ValidateRange(1, [int]::MaxValue)]
        [int] $Count,

        [Parameter(Mandatory, ParameterSetName = 'Place')]
        [double[]] $Place,

        [ValidateSet('OKLab', 'RGB', 'LinearRGB', 'OKLCH', 'HSL', 'HSV', 'Lab', 'LCh')][string] $GradientSpace = 'OKLab',
        [ValidateSet('Shorter', 'Longer', 'Increasing', 'Decreasing')][string] $GradientHue = 'Shorter',
        [ValidateSet('Linear', 'InSine', 'OutSine', 'InOutSine', 'InQuad', 'OutQuad', 'InOutQuad', 'InCubic', 'OutCubic', 'InOutCubic', 'InQuart', 'OutQuart', 'InOutQuart', 'InQuint', 'OutQuint', 'InOutQuint', 'InExpo', 'OutExpo', 'InOutExpo', 'InCirc', 'OutCirc', 'InOutCirc', 'InBack', 'OutBack', 'InOutBack', 'InElastic', 'OutElastic', 'InOutElastic', 'InBounce', 'OutBounce', 'InOutBounce')][string] $GradientEasing = 'Linear',
        [ValidateSet('None', 'Repeat', 'Mirror')][string] $GradientRepeat = 'None',
        [ValidateSet('Forward', 'Reverse', 'CenterOut', 'EdgesIn')][string] $GradientDirection = 'Forward',
        [ValidateRange(0, [int]::MaxValue)][int] $GradientSteps = 0
    )

    if ($null -eq $script:CachedColorTable) {
        $script:CachedColorTable = Get-ColorTableWithRGB
    }
    # The color names the table lacks, each warned about once
    $unknownColorNames = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)

    $colors = Resolve-GradientName -Values $Gradient
    if ($colors.Count -lt 2) {
        $PSCmdlet.ThrowTerminatingError([System.Management.Automation.ErrorRecord]::new(
            [System.ArgumentException]::new("Gradient requires at least 2 colors (received $($colors.Count))."), 'GradientTooFewColors',
            [System.Management.Automation.ErrorCategory]::InvalidArgument, $null))
    }
    $split = Split-GradientPlace -Values $colors
    $colors = ConvertTo-ColorFormList -Values $split.Colors

    if ($PSCmdlet.ParameterSetName -eq 'Count') {
        $rgbs = New-GradientColorArray -Colors $colors -Places $split.Places -Steps $Count -Mode TrueColor -Space $GradientSpace -Hue $GradientHue -Easing $GradientEasing -Repeat $GradientRepeat -Direction $GradientDirection -Bands $GradientSteps
        # Copies, so a change to one leaves the gradients the module keeps alone
        foreach ($rgb in $rgbs) {
            , ([int[]]$rgb.Clone())
        }
        return
    }
    $options = [ColorMath]::GradientOptions($GradientSpace, $GradientHue, $GradientEasing, $GradientRepeat, $GradientDirection, $GradientSteps)
    $stops = ConvertTo-GradientStopRgb -Colors $colors
    foreach ($at in $Place) {
        , [ColorMath]::GradientRgbAt($stops, $split.Places, $at, $options)
    }
}