SmartyP
SmartyP

Reputation:

Converting Int to Color in C# for Silverlight's WriteableBitmap

In Silverlight 3 there is now a WriteableBitmap which provides get/put pixel abilities. This can be done like so:

// 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;

Basically, setting a Pixel involves setting its color, and that comes by bitshifting the alpha, red, blue, green values into an integer.

My question is, how would you turn an integer back to a Color? What goes in the missing spot in this example:

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

Thanks for any help you might have, I'm just not up on my bit shifting and I'm sure others will run into this roadblock at some point.

Upvotes: 10

Views: 17003

Answers (7)

Bill Reiss
Bill Reiss

Reputation: 3460

What has not been covered is that WriteableBitmap uses premultiplied ARGB32 so if you have a semitransparent pixel the R, G, and B values are scaled from 0 to the Alpha value.

To get the Color value back, you need to do the opposite and scale it back up to 0 to 255. Something as shown below.

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

Upvotes: 2

Judah Gabriel Himango
Judah Gabriel Himango

Reputation: 60041

I think something like this should work:

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;
}

Once you have the bytes, getting colors is easy with any of the various Color APIs.

Upvotes: 0

A1exandr Belan
A1exandr Belan

Reputation: 4780

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));
}

and using:

Color c = colorAsInt.ToColor()

Upvotes: 0

Scott Ivey
Scott Ivey

Reputation: 41588

You could possibly use BitConverter.GetBytes() to convert your int to a byte array that would work with the overloads of FromArgb that silverlight has...

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]); 

Upvotes: 4

SmartyP
SmartyP

Reputation: 1359

using the reflector i found how R,G,B are parsed in the standard .net call (not available in Silverlight):

System.Drawing.ColorTranslator.FromWin32()

from that i guessed how to get the alpha channel as well, and this does the job:

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

Upvotes: 7

Sam Harwell
Sam Harwell

Reputation: 99979

You might be looking for the ColorTranslator class, but I'm not sure it's available in SilverLight or what you need. It's absolutely a good one to be aware of though.

Edit: Here was one person's suggestion (use reflection to duplicate the class, so from then on you have a converter available that people are already familiar with).

Upvotes: 0

Nelson
Nelson

Reputation: 464

Color.FromArgb(intVal)

Upvotes: -1

Related Questions