Конвертировать argb в строку - PullRequest
4 голосов
/ 18 февраля 2020

Какой метод позволяет преобразовать ARGB в строку как 'int, int, int'? Пример. Цвет фона $Main устанавливается в виде строки '0, 100, 200'. Return $Main.BackColor дает ARGB, но не строку '0, 100, 200':

$Main  = [System.Windows.Forms.Form] @{
    BackColor = '0, 100, 200'
}

$Main.BackColor
--------------
R             : 0
G             : 100
B             : 200
A             : 255
IsKnownColor  : False
IsEmpty       : False
IsNamedColor  : False
IsSystemColor : False
Name          : ff0064c8

Метод To.String() возвращает результат Color [A=255, R=0, G=100, B=200]. Это не то, что ожидается.

На данный момент я делаю это:

 ('R', 'G', 'B').ForEach({ $Main.BackColor.$_ }) -join ', '

--------------
0, 100, 200

Однако я надеюсь, что есть специальные методы для преобразования как ARGB в string, как string до ARGB. Каковы эти методы? Спасибо

Ответы [ 4 ]

5 голосов
/ 18 февраля 2020

Однако я надеюсь, что есть специальные методы для преобразования как argb в строку, как string в argb. Что это за методы?

Вы бы так подумали, но, насколько мне известно, для этого, к сожалению, нет встроенного двустороннего преобразования.

Вот пара что вы можете сделать вместо этого:

Создайте свою собственную ConvertFrom-Color функцию:

function ConvertFrom-Color
{
    param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [System.Drawing.Color[]]$InputColor
    )

    process {
        foreach($color in $InputColor){
            $color.R,$color.G,$color.B -join ', '
        }
    }
}

И используйте при необходимости:

PS C:\> $colorString = $Main.BackColor |ConvertFrom-Color
PS C:\> $colorString
0, 100, 200

Используйте [int]

Цвет ARGB состоит из 4 1-байтовых каналов, которые идеально вписываются в 32-разрядное целое число. Если вам нужно передать отдельный цвет, используя один аргумент, это уже поддерживается:

PS C:\> $color = [System.Drawing.Color]'0,100,100'
PS C:\> $color.ToArgb()
-16751516
PS C:\> $argbValue = $color.ToArgb()
PS C:\> [System.Drawing.Color]::FromArgb($argbValue)

R             : 0
G             : 100
B             : 100
A             : 255
IsKnownColor  : False
IsEmpty       : False
IsNamedColor  : False
IsSystemColor : False
Name          : ff006464

Как и в случае с вашим начальным строковым представлением, стоит подчеркнуть, что преобразование из представления [int] работает как с явным приведение и неявные преобразования при назначении типизированным свойствам:

$argbValue = -16751516
# This works just fine
[System.Drawing.Color]$argbValue
# As does this
[System.Windows.Forms.Form]@{ BackColor = $argbValue }

Переопределение Color.ToString()

Поскольку вас интересует изменение поведения по умолчанию строковое представление System.Drawing.Color, вы также можете переопределить реализацию метода ToString():

Update-TypeData -TypeName System.Drawing.Color -MemberType ScriptMethod -MemberName ToString -Value {
    $this.psobject.Properties['R','G','B'].Value -join ', '
} -Force

Теперь все экземпляры [System.Drawing.Color] будут использовать ваш собственный метод ToString() при преобразовании в строку:

PS C:\> "$($Main.BackColor)"
0, 100, 200
3 голосов
/ 19 февраля 2020

На этот вопрос есть несколько хороших и инициативных ответов, но, похоже, все они упустили правильный путь , используя преобразователи типов. Существует ColorConverter, ответственный за ConvertTo и ConvertFrom String / Color:

$Color = [System.Drawing.Color]'0, 100, 200'
[System.Drawing.ColorConverter]::new().ConvertToString($Color)
# Result: 0, 100, 200

Это тот же класс, который используется PropertyGrid для преобразования строки до Color или Color и наоборот.

Он также позаботится о A элементе цвета, например, если вы создадите цвет, такой как 100, 0, 100, 200. Это решение автоматически включает или игнорирует A часть всякий раз, когда требуется:

$Color = [System.Drawing.Color]'100, 0, 100, 200'
[System.Drawing.ColorConverter]::new().ConvertToString($Color)
# Result: 100, 0, 100, 200
3 голосов
/ 18 февраля 2020

Полезный ответ Резы Агаи показывает правильное решение, а Отличный ответ Матиаса Р. Джессена показывает надежные альтернативы.

Позвольте мне дополнить их прагматикой c взломать ; в то время как получение сериализуемых представлений из строк for-display (.ToString()), как правило, не рекомендуется, формат под рукой вряд ли изменится таким образом, что это нарушит:

PS> $Main.BackColor -replace '[^\d,]'  # remove all chars. except digits and commas
255,0,100,200

Примечание. Выше приведено альфа-значение, в отличие от исходной входной строки; однако приведение к [System.Drawing.Color] работает одинаково хорошо.

1 голос
/ 18 февраля 2020

Насколько я знаю, в System.Drawing.Color нет специального формата строки. Вам нужно пользовательское преобразование. Вы можете использовать свой метод или любой другой. Я бы использовал пользовательское выражение и интерполяцию строк:

$c = [System.Drawing.Color]'0, 100, 200'

#simulate array
$c,$c | select @{N="Color";E={"$($_.R), $($_.G), $($_.B)"}}

Результат:

Color      
-----      
0, 100, 200
0, 100, 200
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...