locked
Reading/Writing to an IBuffer

    Question

  • I would like to read/write to the WriteableBitmap::Pixels property which is an IBuffer.  IBuffer only has two properties, Capacity and Length.  I would like to get access to the buffer pointer's contents.

    MSDN points says IBuffer is used by the IInput/OutputStreams.  I cannot seem to find a concrete implementation of these classes in the WinRT.  In C#, you simply do a buffer.AsStream().

    Thanks for any help!

    Thursday, October 06, 2011 2:53 AM

Answers

  • This issue has been identified, and it should be a more straightforward task in the future. I could not locate a customer bug on this however is anyone would like to make their voice heard on this subject.

    Thanks,

    -David

    In case you haven't seen this template on filing a bug / feedback on the Developer Preview:

    Thank you for posting your feedback, we want to make sure we get the right info including your log files.  Can you also submit feedback using the Windows Feedback Tool from the Connect Site associated with your Windows Developer Preview program? If you’re an MSDN subscriber, the information on how to join the Connect program is included on the download page where you installed Windows Developer Preview.  There’s a link to the Connect site and an invitation code that you can click on to join using a Windows Live ID account. If you’re not an MSDN subscriber follow this limited use link to join the Connect program and then follow the steps here

     

     

    Tuesday, October 25, 2011 10:25 PM
    Moderator

All replies

  • Unfortunately, that's not supported at the moment. See this thread (similar but in the C# forum) :

    http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/39b3c702-caed-47e4-b7d3-b51d75cbca9b/

     


    http://blog.voidnish.com
    Thursday, October 06, 2011 3:14 AM
  • Thanks Nishant.  The reply by Wes Haggard in that thread makes it sound like it is possible to read/write the pixel data...just there is no Render() method (which is ok for me right now).

     

     

    Thursday, October 06, 2011 3:18 AM
  • Wes Haggard's approach suggests using an extension method that returns a .NET Stream. That's not very useful from a C++ perspective.

    What makes this trickier is that the extension methods do not have any code in them (in the assemblies). They just return false (or are empty). It seems the C# compiler or perhaps the CLR dynamically patches up these functions at runtime. Else we could at least have tried to emulate in C++ what those extension methods do to get the underlying data.


    http://blog.voidnish.com
    Thursday, October 06, 2011 3:26 AM
  • I'm not 100% on this, but by looking at the .NET assemblies in reflector, there seems to be an unpublished interface for getting the buffer:

    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("905a0fef-bc53-11df-8c49-001e4fc686da")]
    internalinterfaceIBufferInternal
    {
        byte* Buffer { [SecurityCritical] get; }
    }
    
    • Proposed as answer by pepone.onrez Wednesday, May 09, 2012 3:59 PM
    • Unproposed as answer by pepone.onrez Wednesday, May 09, 2012 3:59 PM
    Thursday, October 06, 2011 3:28 AM
  • [I posted this a few minutes ago but for some reason the post vanished.]

    Good catch there. That seems to be basically what the C# extension method does too. Obviously not so useful from a practical perspective, although it's good to know what happens there.


    http://blog.voidnish.com
    Thursday, October 06, 2011 3:47 AM
  • Ok, I think I figured it out...though I'm not sure if its the "right" way..but surely its the undocumented way :)

    Here's the code:

    #include "MainPage.xaml.h"
    #include <Windows.h>
    #include <INITGUID.H>
    
    using namespace Windows::UI::Xaml;
    using namespace Windows::UI::Xaml::Controls;
    using namespace Windows::UI::Xaml::Data;
    using namespace Application1;
    using namespace Windows::UI::Xaml::Media::Imaging;
    using namespace Windows::Storage::Streams;
    
    //905a0fef-bc53-11df-8c49-001e4fc686da
    DEFINE_GUID(IID_IBufferInternal, 0x905a0fef, 0xbc53, 0x11df, 
        0x8c, 0x49, 0x00, 0x1e, 0x4f, 0xc6, 0x86, 0xda);
    struct IBufferInternal : IUnknown
    {
    	STDMETHOD(GetBuffer)(unsigned char** c) = 0;
    };
    
    MainPage::MainPage()
    {
        InitializeComponent();
    	
    	wb = ref new WriteableBitmap(320, 240);
    	 
    	auto buffer = wb->PixelBuffer;
    
    	IUnknown* pUnk = reinterpret_cast<IUnknown*>(buffer);
    
    	IBufferInternal* pBufferInternal = nullptr;
    	HRESULT hr = pUnk->QueryInterface(IID_IBufferInternal, (void**)&pBufferInternal);
    
    	unsigned char* pBuff = nullptr;
    	pBufferInternal->GetBuffer(&pBuff);
    }
    

    Thursday, October 06, 2011 5:14 AM
  • Nice work :-) [highly risky to try and use that in actual code though since you can't be sure the internal interface will remain in later builds].
    http://blog.voidnish.com
    • Proposed as answer by fatowl1 Friday, June 28, 2013 3:50 AM
    Thursday, October 06, 2011 5:38 AM
  • Agreed!  Though one can say the same about the entire pre-release package :)
    Thursday, October 06, 2011 5:47 AM
  • Just curious, what use is a WritableBitmap that you cannot actually either write or inspect the contents of?  I ask that in all seriousness -- is there a useful usage scenario for such an object?
    Thursday, October 06, 2011 1:58 PM
  • This issue has been identified, and it should be a more straightforward task in the future. I could not locate a customer bug on this however is anyone would like to make their voice heard on this subject.

    Thanks,

    -David

    In case you haven't seen this template on filing a bug / feedback on the Developer Preview:

    Thank you for posting your feedback, we want to make sure we get the right info including your log files.  Can you also submit feedback using the Windows Feedback Tool from the Connect Site associated with your Windows Developer Preview program? If you’re an MSDN subscriber, the information on how to join the Connect program is included on the download page where you installed Windows Developer Preview.  There’s a link to the Connect site and an invitation code that you can click on to join using a Windows Live ID account. If you’re not an MSDN subscriber follow this limited use link to join the Connect program and then follow the steps here

     

     

    Tuesday, October 25, 2011 10:25 PM
    Moderator
  • So, what's the deal now, 7 months later?  Can we read / write to the pixels?  How?

    Thursday, May 31, 2012 2:16 PM
  • Yes. The Consumer Preview introduced the IBufferByteAccess interface to expose the bytes in the IBuffer. There are a number of threads discussing this. You can also load the buffer into a DataReader with DataReader.FromBuffer

    --Rob
    Thursday, May 31, 2012 2:51 PM
    Owner