Как я могу прочитать цвет пикселя из BitmapImage в Silverlight? - PullRequest
1 голос
/ 08 мая 2009

У меня есть экземпляр BitmapImage в Silverlight, и я пытаюсь найти способ прочитать информацию о цвете каждого пикселя в изображении. Как я могу это сделать? Я вижу, что в этом классе есть метод CopyPixels(), который записывает информацию о пикселях в передаваемый вами массив, но я не знаю, как считывать информацию о цвете из этого массива.

Как я могу это сделать?

Ответы [ 3 ]

2 голосов
/ 22 октября 2009

Найдите класс WriteableBitmap в Silverlight 3. Этот класс имеет член Pixels, который возвращает пиксельные данные растрового изображения в массиве int.

Пример с преобразованием. bi является BitmapImage объектом.

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;
0 голосов
/ 23 мая 2013

Во-первых, вы должны использовать WritableBitmap, чтобы получить коллекцию пикселей: WriteableBitmap bmp = new WriteableBitmap(bitmapImageObj);. Каждый пиксель представлен как 32-разрядное целое число. Я сделал структуру, которая просто помогает разбить целое число на четыре байта (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);
    }
}

Вот пример того, как его можно использовать для изменения значения красного:

BitmapPixel pixel = new BitmapPixel(bmp.Pixels[0]);
pixel.R = 255;
bmp.Pixels[0] = pixel.ToInt32();

Также хотелось бы отметить, что WriteableBitmap.Pixels в формате Premultiplied RGB. Эта статья объяснит, что это значит. А вот как компенсация осуществляется с помощью структуры BitmapPixel:

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();
    }
}
0 голосов
/ 08 мая 2009

Это невозможно с текущим растровым API в текущей выпущенной бета-версии Silverlight 3.

Файл Silverlight BitmapImage не имеет метода CopyPixels. Пожалуйста, смотрите документацию MSDN здесь .

...