Преобразование Int в цвет в С# для Silverlight WriteableBitmap

В Silverlight 3 теперь есть WriteableBitmap, который обеспечивает возможности get/put pixel. Это можно сделать так:

// setting a pixel example
WriteableBitmap bitmap = new WriteableBitmap(400, 200);
Color c = Colors.Purple;
bitmap.Pixels[0] = c.A << 24 | c.R << 16 | c.G << 8 | c.B;

В принципе, установка Pixel включает настройку его цвета, и это происходит путем битового смещения значений альфа, красного, синего, зеленого в целое число.

Мой вопрос: как бы вы вернули целое число в цвет? Что находится в отсутствующем месте в этом примере:

// getting a pixel example
int colorAsInt = bitmap.Pixels[0];
Color c;
// TODO:: fill in the color c from the integer ??

Спасибо за любую помощь, которую вы могли бы иметь, я просто не в курсе своего смещения, и я уверен, что в какой-то момент другие будут сталкиваться с этим препятствием.

Ответ 1

используя отражатель, я нашел, как R, G, B анализируются в стандартном вызове .net(недоступно в Silverlight):

System.Drawing.ColorTranslator.FromWin32()

из этого я угадал, как получить альфа-канал, а это делает работу:

Color c2 = Color.FromArgb((byte)((colorAsInt >> 0x18) & 0xff), 
                          (byte)((colorAsInt >> 0x10) & 0xff), 
                          (byte)((colorAsInt >> 8) & 0xff), 
                          (byte)(colorAsInt & 0xff));

Ответ 2

Вы можете использовать BitConverter.GetBytes() для преобразования вашего int в массив байтов, который будет работать с перегрузками FromArgb, что silverlight имеет...

Color.FromArgb(BitConverter.GetBytes(intVal)); 

// or if that doesn't work
var bytes = BitConverter.GetBytes(intVal);
Color.FromArgb(bytes[3], bytes[2], bytes[1], bytes[0]); 

Ответ 3

Что не было рассмотрено, так это то, что WriteableBitmap использует премультиплексный ARGB32, поэтому, если у вас есть полупрозрачный пиксель, значения R, G и B масштабируются от 0 до значения Alpha.

Чтобы вернуть значение цвета, вам нужно сделать обратное и масштабировать его до 0-255. Что-то, как показано ниже.

r = (byte)(r * (255d / alpha))

Ответ 4

Color.FromArgb(intVal)

Ответ 5

Возможно, вы ищете класс ColorTranslator, но я не уверен, что он доступен в SilverLight или что вам нужно. Это абсолютно хороший, о котором нужно знать.

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

Ответ 6

public static Color ToColor(this uint argb)
{
    return Color.FromArgb((byte)((argb & -16777216) >> 0x18),
                          (byte)((argb & 0xff0000) >> 0x10),
                          (byte)((argb & 0xff00) >> 8),
                          (byte)(argb & 0xff));
}

и используя:

Color c = colorAsInt.ToColor()

Ответ 7

Я думаю, что что-то вроде этого должно работать:

public byte[] GetPixelBytes(WriteableBitmap bitmap)
{
   int[] pixels = bitmap.Pixels;
   int length = pixels.Length * 4;
   byte[] result = new byte[length]; // ARGB
   Buffer.BlockCopy(pixels, 0, result, 0, length);
   return result;
}

Как только у вас есть байты, получение цветов легко с помощью любого из различных API-интерфейсов цветов.