Mohammad Tashani
Mohammad Tashani

Reputation: 103

How to do fast image processing in a WinRT application?

I'm working on a WinRT app that should require some image processing. i use the WriteableBitmapexand i try change color of particular pixel that on an ellipse in my image. but my solution is very very slow. About several minutes after tap in image. Why this solution is so slow? and What is the alternative way?

private void myimage_Tapped(object sender, TappedRoutedEventArgs e)
{
    var xcor = e.GetPosition(sender as UIElement).X;
    var ycor = e.GetPosition(sender as UIElement).Y;
    Image ws = sender as Image;

    int x = (int)(imag.PixelWidth * xcor / ws.ActualWidth);
    int y = (int)(imag.PixelHeight * ycor / ws.ActualHeight);
    var color = imag.GetPixel(x, y);
    if (color.B != 0 && color.G != 0 && color.R != 0)
    {
        while (color.B != 0 && color.G != 0 && color.R != 0 && x < imag.PixelWidth)
        {
            x = x+1;
            y = (int)(imag.PixelHeight * ycor / ws.ActualHeight);
            while (color.B != 0 && color.G != 0 && color.R != 0 && y < imag.PixelHeight)
            {
                y = y + 1;
                color = imag.GetPixel(x, y);
                imag.SetPixel(x, y, Colors.Red);
            }

        }
    }
}

Upvotes: 0

Views: 97

Answers (1)

aybe
aybe

Reputation: 16662

  1. Use BitmapContext, because Set/GetPixel are very very slow, actually each time you call them they open/close a BitmapContext

  2. Review your logic because honestly it doesn't make any sense to me, or explain what you're trying to achieve

Here's an example on how to use a context along a few helpers:

var bitmap = BitmapFactory.New(2048, 2048);
using (var context = bitmap.GetBitmapContext(ReadWriteMode.ReadWrite))
{
    Func<int, int, int> getPixel = (x, y) =>
    {
        var offset = y*bitmap.PixelWidth + x;
        return offset;
    };

    Action<int, int, int> setPixel = (x, y, c) =>
    {
        var offset = getPixel(x, y);
        context.Pixels[offset] = c;
    };

    Func<Color, int> toInt32 = c =>
    {
        var i = c.A << 24 | c.R << 16 | c.G << 8 | c.B;
        return i;
    };
    for (var y = 0; y < bitmap.PixelHeight; y++)
    {
        for (var x = 0; x < bitmap.PixelHeight; x++)
        {
            var color = Color.FromArgb(
                255,
                (byte) ((float) x/bitmap.PixelWidth*255),
                (byte) ((float) y/bitmap.PixelHeight*255),
                255);
            var int32 = toInt32(color);
            setPixel(x, y, int32);
        }
    }
}

Upvotes: 2

Related Questions