Правильный способ упаковки цветов BGRA и ARGB в int - PullRequest
0 голосов
/ 25 сентября 2019

В SharpDx BGRA смещение для red равно 16:

(color >> 16) & 255

см. здесь .

Но в .NET, ARGBсдвиг для red также равен 16:

private const int ARGBRedShift = 16;

см. здесь и здесь и здесь .

Я в замешательстве, что правильно?

это (как .NET):

public int PackeColorToArgb()
{
    int value = B;
    value |= G << 8;
    value |= R << 16;
    value |= A << 24;

    return (int)value;
}

или это (как SharpDx):

public int PackeColorToArgb()
{
    int value = A;
    value |= B << 8;
    value |= G << 16;
    value |= R << 24;

    return (int)value;
}

Для .Net 0xFFFF0000 - это Argb Red,но для SharpDx это Bgra Red.что правильно?

1 Ответ

1 голос
/ 26 сентября 2019

Правильный способ упаковки цветов BGRA и ARGB в int

Это зависит от того, где вы собираетесь использовать int.Но для двух приведенных вами примеров вы упаковываете байтовые значения в целочисленное значение точно таким же образом.Они оба "правы".Отличается только имя, и вы можете иметь много разных имен для одной и той же вещи.

Важно, что ваш второй пример кода - предположительно "правильный" для SharpDx - не правильный дляЦветовой формат, о котором вы спрашиваете.Вы можете видеть прямо в исходном коде, на который вы ссылаетесь, когда вы упаковываете байты в порядке A, B, G и R, LSB в MSB, правильный порядок компонентов на самом деле BGRA (опять же, LSB в MSB).

Ваш второй пример кода должен выглядеть точно так же, как и первый.

Длинная версия ...

Как видно из двух ссылок на исходный код, которые вы отметили, фактические форматы идентичны .Таким образом, формат от каждого API хранит значения байтов для каждого компонента цвета в том же порядке, в пределах одного 32-разрядного целого числа: синий в младших 8 битах, затем зеленый, затем красный, затем альфа в старших 8 битах.

Проблема в том, что нет единого стандарта для именования таких форматов.В контексте .NET они перечисляют компоненты цвета в порядке с прямым порядком байтов (что можно считать немного ироничным, поскольку большая часть экосистемы Windows основана на аппаратном порядке с прямым порядком байтов… но, см. Ниже).Т.е. самый старший байт указан первым: "ARGB" .Я называю это имя «порядком с прямым порядком байтов» просто потому, что это имя соответствует сценарию, в котором 32-разрядное целое число сохраняется в памяти в последовательности из 4 байтов на компьютере, работающем в режиме с прямым порядком байтов.Порядок инициалов компонентов в имени совпадает с порядком их появления в этом контексте.

С другой стороны, в контексте SharpDx имя соответствует порядку байтов, который вы видитена оборудовании с прямым порядком байтов.Синий байт будет первым в памяти, затем зеленый, красный и, наконец, альфа.

Фактически, оба они несколько произвольны.В то время как большинство основных ПК теперь работают в режиме с прямым порядком байтов, что говорит в пользу схемы именования SharpDx (которая унаследована от среды DirectX), оба этих API также можно найти на оборудовании с прямым порядком байтов, особенно.NET Core набирает обороты.И во многих случаях программисту, использующему API, даже не важно, в каком порядке расположены байты. Для кода, который имеет дело с отдельными байтами, это все же важно, но в большинстве случаев речь идет просто озная, в каком формате инструменты, которые вы используете, вы записываете растровые изображения, а затем убедитесь, что вы указали правильный формат для API.

Все это говорит, я подозреваю, что основная причина расхождения меньшеделать с прямым порядком байтов по сравнению с прямым порядком байтов и больше с философскими различиями между людьми, ответственными за API.Дело в том, что даже на оборудовании с прямым порядком байтов формат SharpDx для пикселя, в котором компоненты отображаются в памяти в порядке BGRA, будет "BGRA" .Потому что растровые форматы не меняются только потому, что аппаратный режим порядка байтов отличается.Пиксель не целое число.Это просто последовательность байтов.Отличие будет заключаться в том, что значения сдвига должны быть разными, т. Е. Обращенными, так что для кода, который обрабатывает пиксель как одно 32-разрядное целое число, он может правильно обращаться к отдельным компонентам.

Вместо этого мне кажется, что дизайнеры .NET осознали, что пользователи их API будут в большинстве случаев иметь дело с цветами на высоком уровне (например, установив цвет пера или кисти), а не на пикселе.уровень растровых изображений и, следовательно, наименование формата пикселей в соответствии с обычным порядком имеет больше смысла.С другой стороны, в SharpDx люди гораздо чаще имеют дело с низкоуровневыми пиксельными данными, и в этом контексте имеет больше смысла имя, которое отражает фактическую побочную последовательность компонентов для пикселя.

Действительно, код .NET, на который вы ссылались, не включает растровые данные.Структура Color только когда-либо имеет дело с одиночными значениями int одновременно с номенклатурой "ARGB" .Поскольку концептуально мы представляем числа в формате с прямым порядком байтов (даже для десятичного, то есть с самыми старшими цифрами в первую очередь), ARGB более удобочитаем.С другой стороны, в областях .NET, которые включают порядок байтов в пиксельных форматах, вы обнаружите, что наименование возвращается к представлению фактического порядка байтов, например, список PixelFormats введено с WPF.

Ясно, как грязь, верно?:)

...