1

I'm trying to learn how to interact with the some of the WinRT (Metro) objects for images. Basically, I'm working towards creating a "GetPixel" and "SetPixel" method that's easy to use (similiar to what's in System.Drawing.Bitmap that can't be used in Metro apps).

For testing, I created a "Bitmap" class. It loads based off of a IRandomAccessStream that I get from the Metro file picker control. I'm able to load the pixel data into a Byte array and then create a BitmapImage from it that renders correctly on a XAML form when I toss it into an Image control.

Here's my issue, I can look at the byte array and see the individual ARGB values, but, it has far less pixels than it should. For example, the image I'm loading is 254x197 pixels (254*197*4=200,152). When I load my Byte array though with the below code, it's only got 16,382 bytes (which also doesn't equally divide by 4). I assume, this is compressed?.. I dunno.

My question is, what am I doing wrong.. I would like to return the 200,152 bytes representing the 50,038 pixels that I should have so I can create GetPixel(x,y) and a SetPixel(x,y,Color) methods.

Public Class Bitmap

    Public Sub New()

    End Sub

    Public Async Function Load(s As Windows.Storage.Streams.IRandomAccessStream) As Task
        Dim dr As New DataReader(s.GetInputStreamAt(0))
        Await dr.LoadAsync(s.Size)
        Me.Pixels = New Byte(s.Size - 1) {}
        dr.ReadBytes(Me.Pixels)

        ' We're going to get the height and the width of the image this way. ;)
        Dim bi As New BitmapImage
        Dim stream As New MemoryStream(Me.Pixels)
        bi.SetSource(New RandomStream(stream))
        Me.Width = bi.PixelWidth
        Me.Height = bi.PixelHeight
    End Function

    Public Function ToBitmapImage() As BitmapImage
        Dim bi As New BitmapImage
        Dim stream As New MemoryStream(Me.Pixels)
        bi.SetSource(New RandomStream(stream))
        Return bi
    End Function

    Public Property Pixels As Byte()
    Public Property Width As Integer = 0
    Public Property Height As Integer = 0

End Class
5
  • One comment.. the RandomStream is a class that implements IRandomAccessStream and converts a Stream into it. Commented Apr 16, 2012 at 20:16
  • You need to learn about the JPEG or PNG file formats. Commented Apr 16, 2012 at 20:18
  • What should I search for to learn this? I assume that means I need to convert the compressed JPEG/PNG into a raw pixel format? Do you have any direction.. my searches for this with WinRT are coming up slim (I maybe using the wrong keywords)? Is there something in WinRT to handle this? Commented Apr 16, 2012 at 20:22
  • You can read the Wikipedia articles. However, you should not re-invent the wheel; there should be spme way to read the decoded BitmapImage in WinRT. Commented Apr 16, 2012 at 20:27
  • That's what I'm searching for but haven't found yet. Commented Apr 16, 2012 at 23:34

1 Answer 1

6

I made a WinRT version of the WriteableBitmapEx that does this.

Basically you need to load the image into a WriteableBitmap, then access its pixel buffer by calling PixelBuffer.AsStream(). Then you need to seek the stream to the x,y position (y * bmp.PixelWidth + x) to be able to read the pixel value. Then also convert the 4 bytes you get to the pixel format that works for you.

EDIT*

WriteableBitmapEx does natively support WinRT now.

Sign up to request clarification or add additional context in comments.

2 Comments

Excellent. :) I was looking for WinRT ports of this. I'm going to go take a look at this and then I'll be back to mark the answer. :) Much appreciated!
Yes, I wanted to help René with the port to WinRT, but I seem to have based my code on an older version of WBX and I never found the time to rebase it on the latest version and get it checked in.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.