3

I have an image source behind IImageProvider interface, and I'm trying to access its pixels.

There is a method inside IImageProvider: imageProvider.GetBitmapAsync(bitmapToFill)

  • I can't get WriteableBitmap because I'm running on a non UI thread. I can't instantiate one empty WriteableBitmap to write to which is unfortunate because I can access pixels from it..
  • I can fill a Bitmap object with the data, but there is no way to access its pixels on Windows Phone (it is missing system.drawing...)

How can I access individual pixels of the source behind IImageProvider?

David Božjak
  • 16,887
  • 18
  • 67
  • 98
pkovacevic
  • 33
  • 3
  • 1
    Note that the "Bitmap" as used by the Nokia Imaging SDK is not the same as the old System.Drawing one. It's in the Nokia.Graphics.Imaging namespace. – CÅdahl Dec 14 '13 at 21:36

2 Answers2

3

Have you tried this?

var bitmap = await imageSource.GetBitmapAsync(null, OutputOption.PreserveAspectRatio);
var pixels = bitmap.Buffers[0];
for (uint i = 0; i < pixels.Buffer.Length; i++)
    {
        var val = pixels.Buffer.GetByte(i);
    }
  • i = R ... [0]
  • i+1 = G ... [1]
  • i+2 = B ... [2]
  • i+3 = A ... [3]

and so on

imageSource is your IImageProvider, I tested it with BufferImageSource.

Igor Ralic
  • 14,975
  • 4
  • 43
  • 51
  • Yes, the Buffers collection is where you should look, grabbing the IBuffer(s) there. – CÅdahl Dec 14 '13 at 21:34
  • Worth to mention that you have use System.Runtime.InteropServices.WindowsRuntime namespace in order to have "GetByte" method. – Illidan Mar 31 '14 at 14:57
2

A slightly more efficient option is this.

Create a Bitmap over your own .NET array of (empty) pixels, then using GetBitmapAsync to fill that. Once rendering is done, you can find the result in the original array you passed.

byte[] myPixels = new byte[correctSize]; // You can use a ColorModeDescriptor to calculate the size in bytes here.

using(var wrapperBitmap = new Bitmap(widthAndHeight, colorMode, pitch, myPixels.AsBuffer()))
{
    await interestingImage.GetBitmapAsync(wrapperBitmap, OutputOption.PreserveAspectRatio);
}

// and use myPixels here.
CÅdahl
  • 442
  • 3
  • 13
  • Another note: GetBitmapAsync is essentially shorthand for creating a BitmapRenderer and calling RenderAsync on it. So if you anticipate doing this often and want to avoid overhead, do that instead and store the renderer object. Same goes for the array/bitmap if you can afford to keep the objects in memory. – CÅdahl Dec 14 '13 at 21:56