Reputation: 9275
I have a BitmapImage instance in Silverlight, and I am trying to find a way to read the color information of each pixel in the image. How can I do this? I see that there is a CopyPixels()
method on this class that writes pixel information into the array that you pass it, but I don't know how to read color information out of that array.
How can I do this?
Upvotes: 1
Views: 3938
Reputation: 1767
First, you should use WritableBitmap
to get pixels collection: WriteableBitmap bmp = new WriteableBitmap(bitmapImageObj);
. Each pixel is represented as 32-bit integer. I have made structure, which just helps to splits integer into a four bytes (ARGB).
struct BitmapPixel
{
public byte A;
public byte R;
public byte G;
public byte B;
public BitmapPixel(int pixel)
: this(BitConverter.GetBytes(pixel))
{
}
public BitmapPixel(byte[] pixel)
: this(pixel[3], pixel[2], pixel[1], pixel[0])
{
}
public BitmapPixel(byte a, byte r, byte g, byte b)
{
this.A = a;
this.R = r;
this.G = g;
this.B = b;
}
public int ToInt32()
{
byte[] pixel = new byte[4] { this.B, this.G, this.R, this.A };
return BitConverter.ToInt32(pixel, 0);
}
}
Here is an example of how it could be used to change red value:
BitmapPixel pixel = new BitmapPixel(bmp.Pixels[0]);
pixel.R = 255;
bmp.Pixels[0] = pixel.ToInt32();
Also I would like to mention that WriteableBitmap.Pixels are in Premultiplied RGB format. This article will explain what it means. And here is how compensation done by using BitmapPixel structure:
public static void CompensateRGB(int[] pixels)
{
for (int i = 0; i < pixels.Length; i++)
{
BitmapPixel pixel = new BitmapPixel(pixels[i]);
if (pixel.A == 255 || pixel.A == 0)
continue;
if (pixel.R == 0 && pixel.G == 0 && pixel.B == 0)
{
// color is unrecoverable, get rid of this
// pixel by making it transparent
pixel.A = 0;
}
else
{
double factor = 255.0 / pixel.A;
pixel.A = 255;
pixel.R = (byte)(pixel.R * factor);
pixel.G = (byte)(pixel.G * factor);
pixel.B = (byte)(pixel.B * factor);
}
pixels[i] = pixel.ToInt32();
}
}
Upvotes: 0
Reputation: 21
Look for the WriteableBitmap
class in Silverlight 3. This class has a member Pixels
which returns the bitmap's pixel data in an array of int's.
An example with a transform. bi
is an BitmapImage
object.
Image img = new Image();
img.source = bi;
img.Measure(new Size(100, 100));
img.Arrange(new Rect(0, 0, 100, 100));
ScaleTransform scaleTrans = new ScaleTransform();
double scale = (double)500 / (double)Math.Max(bi.PixelHeight, bi.PixelWidth);
scaleTrans.CenterX = 0;
scaleTrans.CenterY = 0;
scaleTrans.ScaleX = scale;
scaleTrans.ScaleY = scale;
WriteableBitmap writeableBitmap = new WriteableBitmap(500, 500);
writeableBitmap.Render(img, scaleTrans);
int[] pixelData = writeableBitmap.Pixels;
Upvotes: 2