如何在 C++/winrt 中将 svg 加载到 CanvasVirtualControl?
How to load an svg to CanvasVirtualControl in C++/winrt?
我一直在使用 C++/winrt 构建的 UWP 应用程序中成功加载绘图 svg 图像,但在最新版本中发现加载 svg 的调用引发异常。
崩溃发生在一种难以追踪的 IAsync 方法中,但我已将问题缩小到加载 SVG 的那一行。
这通常是循环读取大量文件,但非常简单地减少问题仍然显示问题:
winrt::Microsoft::Graphics::Canvas::UI::Xaml::CanvasVirtualControl resourceCreator
winrt::Windows::Storage::StorageFile nextFile = nullptr;
winrt::Microsoft::Graphics::Canvas::Svg::CanvasSvgDocument nextSvg = nullptr;
winrt::Windows::Storage::Streams::IRandomAccessStream fileStream = nullptr;
//This is called from within the lambda handling CreateResources for the CanvasVirtualControl
//The VirtualControl is provided as the resourceCreator argument
IAsyncAction loadSVGs(winrt::Microsoft::Graphics::Canvas::UI::Xaml::CanvasVirtualControl resourceCreator)
{
nextFile = m_symbol_resource_files.GetAt(i);
fileStream = co_await nextFile.OpenReadAsync();
nextSvg = co_await CanvasSvgDocument::LoadAsync(resourceCreator,fileStream);
}
调用 LoadAsync 失败
exception: winrt:hresult_invalid_argument at memory location 0x0C93F1CB
void resume()const{
->_coro_resume(_Ptr);
}
如果我继续排除异常,我发现资源实际上已经加载并且可以使用。但是如果 运行 在 Visual Studio 之外,应用程序通常会在这一行退出。难道是CanvasVirtualControl不接受?
或者是否有更好的方法从文件加载 svg?我无法计算出 CanvasDocument 的 LoadFromXML,因为它需要一个 System.String 参数,在 C++/winrt 中不可用,并且 winrt std::wstring 作为替代品是不可接受的 [更正:实际上 hstring 会作为参数工作,可以从 std::wstring].
创建
[更新]我还没有创建一个简单的演示项目来显示这种行为,但我想我已经了解了原因并想扩展我的问题。我已经尝试了 CanvasSvgDocument 的 LoadFromXml 和 LoadAsync 方法,其中第二种方法曾经很好,但现在都以同样的方式失败,在我看来 ResourceCreator 参数可能是问题所在。我在 CreateResources 处理程序中创建这些资源,并将发送者 - CanvasVirtualControl - 作为 resourceCreator 传递。但是,为 CanvasSvgDocument 调用列出的参数是 ICanvasResourceCreator。我原以为这是一种便利,可以直接为该参数传递 CanvasVirtualControl(过去也是如此)。但也许这是不正确的,也许过去和现在都被认为是不正确的?如果是这样,如何将 CreateResources 处理程序中的发件人正确传递给 CanvasSvgDocument 方法?
我创建了一个空白应用程序来使用 CanvasVirtualControl 加载 SVG,它运行良好。你能提供一个可以复制的简单样本吗?而且我检查了LoadFromXML方法,它需要的参数是hstring类型而不是System.String.
另外,关于从文件加载svg,是否必须使用win2d加载svg?如果没有,您可以尝试使用 SvgImageSource 的图像控制来加载 svg,如下所示:
.xaml:
<Image x:Name="MyImage" Width="300" Height="200"></Image>
.cpp:
winrt::Windows::Storage::StorageFile nextFile = nullptr;
winrt::Microsoft::Graphics::Canvas::Svg::CanvasSvgDocument nextSvg = nullptr;
winrt::Windows::Storage::Streams::IRandomAccessStream fileStream = nullptr;
nextFile = co_await KnownFolders::PicturesLibrary().GetFileAsync(L"Freesample.svg");
fileStream = co_await nextFile.OpenReadAsync();
SvgImageSource sourcee = SvgImageSource();
co_await sourcee.SetSourceAsync(fileStream);
MyImage().Source(sourcee);
我一直在使用 C++/winrt 构建的 UWP 应用程序中成功加载绘图 svg 图像,但在最新版本中发现加载 svg 的调用引发异常。 崩溃发生在一种难以追踪的 IAsync 方法中,但我已将问题缩小到加载 SVG 的那一行。
这通常是循环读取大量文件,但非常简单地减少问题仍然显示问题:
winrt::Microsoft::Graphics::Canvas::UI::Xaml::CanvasVirtualControl resourceCreator
winrt::Windows::Storage::StorageFile nextFile = nullptr;
winrt::Microsoft::Graphics::Canvas::Svg::CanvasSvgDocument nextSvg = nullptr;
winrt::Windows::Storage::Streams::IRandomAccessStream fileStream = nullptr;
//This is called from within the lambda handling CreateResources for the CanvasVirtualControl
//The VirtualControl is provided as the resourceCreator argument
IAsyncAction loadSVGs(winrt::Microsoft::Graphics::Canvas::UI::Xaml::CanvasVirtualControl resourceCreator)
{
nextFile = m_symbol_resource_files.GetAt(i);
fileStream = co_await nextFile.OpenReadAsync();
nextSvg = co_await CanvasSvgDocument::LoadAsync(resourceCreator,fileStream);
}
调用 LoadAsync 失败
exception: winrt:hresult_invalid_argument at memory location 0x0C93F1CB
void resume()const{
->_coro_resume(_Ptr);
}
如果我继续排除异常,我发现资源实际上已经加载并且可以使用。但是如果 运行 在 Visual Studio 之外,应用程序通常会在这一行退出。难道是CanvasVirtualControl不接受?
或者是否有更好的方法从文件加载 svg?我无法计算出 CanvasDocument 的 LoadFromXML,因为它需要一个 System.String 参数,在 C++/winrt 中不可用,并且 winrt std::wstring 作为替代品是不可接受的 [更正:实际上 hstring 会作为参数工作,可以从 std::wstring].
创建[更新]我还没有创建一个简单的演示项目来显示这种行为,但我想我已经了解了原因并想扩展我的问题。我已经尝试了 CanvasSvgDocument 的 LoadFromXml 和 LoadAsync 方法,其中第二种方法曾经很好,但现在都以同样的方式失败,在我看来 ResourceCreator 参数可能是问题所在。我在 CreateResources 处理程序中创建这些资源,并将发送者 - CanvasVirtualControl - 作为 resourceCreator 传递。但是,为 CanvasSvgDocument 调用列出的参数是 ICanvasResourceCreator。我原以为这是一种便利,可以直接为该参数传递 CanvasVirtualControl(过去也是如此)。但也许这是不正确的,也许过去和现在都被认为是不正确的?如果是这样,如何将 CreateResources 处理程序中的发件人正确传递给 CanvasSvgDocument 方法?
我创建了一个空白应用程序来使用 CanvasVirtualControl 加载 SVG,它运行良好。你能提供一个可以复制的简单样本吗?而且我检查了LoadFromXML方法,它需要的参数是hstring类型而不是System.String.
另外,关于从文件加载svg,是否必须使用win2d加载svg?如果没有,您可以尝试使用 SvgImageSource 的图像控制来加载 svg,如下所示:
.xaml:
<Image x:Name="MyImage" Width="300" Height="200"></Image>
.cpp:
winrt::Windows::Storage::StorageFile nextFile = nullptr;
winrt::Microsoft::Graphics::Canvas::Svg::CanvasSvgDocument nextSvg = nullptr;
winrt::Windows::Storage::Streams::IRandomAccessStream fileStream = nullptr;
nextFile = co_await KnownFolders::PicturesLibrary().GetFileAsync(L"Freesample.svg");
fileStream = co_await nextFile.OpenReadAsync();
SvgImageSource sourcee = SvgImageSource();
co_await sourcee.SetSourceAsync(fileStream);
MyImage().Source(sourcee);