none
求助:将内存中的数据提交给image控件显示遇到的难题 RRS feed

  • 问题

  • 我有一个保存位图数据的(void*)buf和它的(int)size。

    想把这些数据用image控件显示出来。

    我用了两种方法,但是都没能解决我的问题。方法如下,不知道错误在哪,希望有高手能够给予帮助。谢谢。

    方法一:

    	void* PageBuffer = GetPageBuffer(0);//保存有位图各像素数据的buf
    	int nBufSize = FS_Bitmap_GetStride(m_bitmap) * FS_Bitmap_GetHeight(m_bitmap);//位图大小
    	Array<unsigned char,1>^ bufArray = ref new Array<unsigned char,1>((unsigned char*)PageBuffer,nBufSize);
    	auto rasos = ref new InMemoryRandomAccessStream();
    	DataWriter^ dataWriter = ref new DataWriter(rasos->GetOutputStreamAt(0));
    	dataWriter->WriteBytes(bufArray);
    	task<unsigned int>(dataWriter->StoreAsync()).then([this,rasos](unsigned int bytesWritten)
    	{
    		WriteableBitmap^ wb = ref new WriteableBitmap(FS_Bitmap_GetWidth(m_bitmap),FS_Bitmap_GetHeight(m_bitmap));
    		wb->SetSource(safe_cast<IRandomAccessStream^>(rasos));
    		wb->Invalidate();
    		img_page->Source = wb;
    	});


    采用上面的方法可以成功触发image控件的Windows::UI::Xaml::Controls::Image::ImageOpened事件。可是应用会Crash。image控件无法正常显示出图片。

    方法二:

    #include <initguid.h>
    
    DEFINE_GUID(IID_IBufferInternal, 0x905a0fef, 0xbc53, 0x11df, 
        0x8c, 0x49, 0x00, 0x1e, 0x4f, 0xc6, 0x86, 0xda);
    
    /* UNDOCUMENTED INTERFACE.  You have been warned =P */
    struct IBufferInternal : IUnknown
    {
    	STDMETHOD(GetBuffer)(unsigned char** ppBuffer) = 0;
    };
    //---------------------------------提交渲染
    	WriteableBitmap^ wb = ref new WriteableBitmap(FS_Bitmap_GetWidth(m_bitmap),FS_Bitmap_GetHeight(m_bitmap));
    	IUnknown* pUnk = reinterpret_cast<IUnknown*>(wb->PixelBuffer);
    
    	IBufferInternal* pBufferInternal = nullptr;
    
    	/* Get the undocumented interface for accessing the pixel buffer */
    	HRESULT hr = pUnk->QueryInterface(IID_IBufferInternal, 
    										 (void**)&pBufferInternal);
    	
    	hr = pBufferInternal->GetBuffer(&m_pWriteableBitmapBuffer);
    	img_page->Source = wb;
    	memcpy(m_pWriteableBitmapBuffer, PageBuffer, nBufSize);
    	wb->Invalidate();

    使用这个方法image控件可以正常显示图片内容,可是当我更新图片数据的时候WriteableBitmap^ wb不会自动释放资源,导致内存占用急剧上升。

    我的错误在哪呢?

    2012年4月13日 7:08

答案

全部回复

  • 方法一: 加一个  dataWriter->FlushAsync();

    方法二: 你的这个问题在英文论坛那边 MSFT 回答了:http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/d02bd285-5c04-4a44-b9c7-5d5d39e0036f 检查你的引用计数器是否有增加,是否需要显式Release。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    • 已标记为答案 frglig 2012年4月16日 9:49
    2012年4月16日 8:40
    版主
  • 谢谢你的回答!
    方法一:这个该怎么加呢?能否给段具体的代码?谢谢!

    方法二:增加了pUnk->Release();还是存在内存没有释放的问题。能否请问显示Release哪个对象呢?谢谢!

    编辑:方法二这样增加了已经不会存在内存泄漏了。


    • 已编辑 frglig 2012年4月16日 9:28
    2012年4月16日 8:57
  • 先调用 StoreAsync 然后调用 FlushAsync ,注意它们都是异步方法.

    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年4月16日 9:02
    版主
  • 你好。方法一我这样添加还是不行,结果一样的。

    auto rasos = ref new InMemoryRandomAccessStream();
    	rasos->Size = nBufSize;
    	DataWriter^ dataWriter = ref new DataWriter(rasos->GetOutputStreamAt(0));
    	dataWriter->WriteBytes(bufArray);
    	task<unsigned int>(dataWriter->StoreAsync()).then([this,rasos,dataWriter](unsigned int bytesWritten)
    	{
    		/*BitmapImage^ bitmapImagee =ref new BitmapImage();
    		bitmapImagee->DecodePixelHeight = FS_Bitmap_GetHeight(m_bitmap);
    		bitmapImagee->DecodePixelWidth = FS_Bitmap_GetWidth(m_bitmap);
    		bitmapImagee->SetSource(rasos);
    		img_page->Source = bitmapImagee;*/
    		task<bool>(dataWriter->FlushAsync()).then([this,rasos](bool value)
    		{
    			/*WriteableBitmap^ wb = ref new WriteableBitmap(FS_Bitmap_GetWidth(m_bitmap),FS_Bitmap_GetHeight(m_bitmap));
    			wb->SetSource(safe_cast<IRandomAccessStream^>(rasos));
    			wb->Invalidate();
    			img_page->Source = wb;*/
    
    			BitmapImage^ bitmapImagee =ref new BitmapImage();
    			bitmapImagee->DecodePixelHeight = FS_Bitmap_GetHeight(m_bitmap);
    			bitmapImagee->DecodePixelWidth = FS_Bitmap_GetWidth(m_bitmap);
    			bitmapImagee->SetSource(rasos);
    			img_page->Source = bitmapImagee;
    		});
    	});

    上面bytesWritten值是我的数据的大小,没错。value值为true。

    可是使用WriteableBitmap会crash;

    使用BitmapImage会在下面的代码中返回E_NETWORK_ERROR错误码;

    void ReadPage::img_page_ImageFailed_1(Platform::Object^ sender, Windows::UI::Xaml::ExceptionRoutedEventArgs^ e)
    {
    	int kk = 0;
    	kk=1;
    	TB_error->Text = e->ErrorMessage;
    }

    2012年4月16日 9:46
  • "返回E_NETWORK_ERROR错误码"

    我想是你的代码没有权限访问你的文件的所在Path,能否告诉我你的数据来自哪里,是怎么进入到你的 bufArray 的?


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年4月17日 5:32
    版主
  • 数据是解析文件并且处理后得到的,文件位于当前应用的Appx目录底下。bufArray是new 的时候传入数据的。

    Array<unsigned char,1>^ bufArray = ref new Array<unsigned char,1>((unsigned char*)PageBuffer,nBufSize);

    2012年4月17日 5:54