UWP开发细节记录:加载图像文件到D2D位图和D3D纹理
在UWP中加载文件一般先创建 StorageFile 对象,然后调用StorageFile.OpenReadAsync 方法得到一个IRandomAccessStream 接口用来读取数据:
StorageFile image_file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/sample.jpg", UriKind.Absolute));
IRandomAccessStream stream = await image_file.OpenReadAsync();
从一个 IRandomAccessStream 流开始,加载图像的步骤(C++ /CX实现):
1. 转换 IRandomAccessStream^ 到 ISream 接口:
ComPtr<IStream> source_stream;
DX::ThrowIfFailed(::CreateStreamOverRandomAccessStream(stream, IID_PPV_ARGS(&source_stream)));
2. 调用 IWICImagingFactory::CreateDecoderFromStream 方法(假设IWICImagingFactory对象以创建)创建 IWICBitmapDecoder 对象用于图像解码,并最终得到 IWICFormatConverter 对象转换为适合D2D/D3D的位图格式:
ComPtr<IWICBitmapDecoder> decoder;
DX::ThrowIfFailed(_device_resources->GetWicImagingFactory()->CreateDecoderFromStream(source_stream.Get(), nullptr, WICDecodeMetadataCacheOnDemand, &decoder)); ComPtr<IWICBitmapFrameDecode> frame;
DX::ThrowIfFailed(decoder->GetFrame(, &frame)); // Convert the image to a pixel format supported by Direct2D. 32bppPBGRA is guaranteed to be supported on all hardware.
ComPtr<IWICFormatConverter> covert;
DX::ThrowIfFailed(_device_resources->GetWicImagingFactory()->CreateFormatConverter(&covert));
DX::ThrowIfFailed(covert->Initialize(frame.Get(), GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.0f, WICBitmapPaletteTypeCustom));
3. 如果图像用于 D2D ,现在就可以直接用 ID2D1DeviceContext::CreateBitmapFromWicBitmap 方法创建 D2D 位图了:
ComPtr<ID2D1Bitmap1> d2d_bitmap;
DX::ThrowIfFailed(_device_resources->GetD2DDeviceContext()->CreateBitmapFromWicBitmap(covert.Get(), &d2d_bitmap));
4. 如果要用于 D3D 则需要先创建 D3D 纹理:
// 创建D3D纹理用于3D渲染
D3D11_TEXTURE2D_DESC tex_desc = { };
tex_desc.ArraySize = ;
tex_desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
tex_desc.CPUAccessFlags = ;
tex_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
tex_desc.Height = height;
tex_desc.Width = width;
tex_desc.MipLevels = ;
tex_desc.MiscFlags = ;
tex_desc.SampleDesc.Count = ;
tex_desc.SampleDesc.Quality = ;
tex_desc.Usage = D3D11_USAGE_DEFAULT; ComPtr<ID3D11Texture2D> image_texture;
DX::ThrowIfFailed(_device_resources->GetD3DDevice()->CreateTexture2D(&tex_desc, NULL, &image_texture));
5. 从 ID3D11Texture2D 对象中获取 IDXGISurface 接口,D2D和D3D只能通过DXGI进行交互:
ComPtr<IDXGISurface> dxgi_surface;
DX::ThrowIfFailed(image_texture.As(&dxgi_surface));
6. 通过 ID2D1Factory::CreateDxgiSurfaceRenderTarget 方法创建 D2D 渲染目标:
float dpiX = 1.0f;
float dpiY = 1.0f;
_device_resources->GetD2DFactory()->GetDesktopDpi(&dpiX, &dpiY); D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
dpiX,
dpiY
); ComPtr<ID2D1RenderTarget> render_target;
DX::ThrowIfFailed(_device_resources->GetD2DFactory()->CreateDxgiSurfaceRenderTarget(dxgi_surface.Get(), props, &render_target));
7. 通过 ID2D1RenderTarget::CreateBitmapFromWicBitmap 方法创建位图(注意这里不能直接使用第3步创建的位图,是不同的渲染目标,设备相关的位图不能通用):
ComPtr<ID2D1Bitmap> bitmap;
DX::ThrowIfFailed(render_target->CreateBitmapFromWicBitmap(covert.Get(), &bitmap));
8. 绘制位图到渲染目标,实际上也是绘制到 D3D 纹理:
render_target->BeginDraw();
render_target->DrawBitmap(bitmap.Get());
render_target->EndDraw();
参考:MSDN 《Direct2D 和 Direct3D 互操作性概述》
UWP开发细节记录:加载图像文件到D2D位图和D3D纹理的更多相关文章
- UWP开发细节记录:DirectX::XMMATRIX 的坑
这两天写的代码概率性的崩溃在 XMMatrixMultiply() 函数,XMMatrixMultiply() 本身是 inline 函数可以看到崩溃处的代码: vX = _mm_mul_ps(vX, ...
- UWP开发细节记录:WRL::ComPtr 的坑
WRL::ComPtr 取原始指针的地址有两种方式: operator&() 先释放原指针再取地址 GetAddressOf() 直接得到原始指针的地址 显然,operator& ...
- UWP开发细节记录:判断文件类型
StorageFile.ContentType 属性,是 string 类型,用来表示文件内容的 MIME 类型.例如,音乐文件可能有 "audio/mpeg" MIME 类型.( ...
- UWP开发细节记录:IStream 和 IRandomAccessStream^ 以及 IMFByteStream 互转
IStream 和 IRandomAccessStream^ 互转 IRandomAccessStream^ --> IStream: CreateStreamOverRandomAccess ...
- 【记录】尝试用QEMU模拟ARM开发板去加载并运行Uboot,kernel,rootfs【转】
转自:https://www.crifan.com/try_use_qemu_emulate_arm_board_to_load_and_run_uboot_kernel_rootfs/ [背景] 手 ...
- 混合开发(一)——WebView开发高级技巧之加载网页以及JavaScript,加载进度条
混合开发(一)--WebView开发高级技巧之加载网页以及JavaScript,加载进度条 现在关于混合开发也越来越多了,很多人喜欢跟随,比如HB,比如RN,其实这东西很早就有这么一个概念了,而且说实 ...
- 微信小程序开发动感十足的加载动画--都在这里!
代码地址如下:http://www.demodashi.com/demo/14242.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...
- 从零开始实现ASP.NET Core MVC的插件式开发(六) - 如何加载插件引用
标题:从零开始实现ASP.NET Core MVC的插件式开发(六) - 如何加载插件引用. 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/1171 ...
- hive--udf函数(开发-4种加载方式)
UDF函数开发 标准函数(UDF):以一行数据中的一列或者多列数据作为参数然后返回解雇欧式一个值的函数,同样也可以返回一个复杂的对象,例如array,map,struct. 聚合函数(UDAF):接受 ...
随机推荐
- Scala使用Akka模拟RPC机制代码
上代码: 另一个版本(自己加注释):http://www.cnblogs.com/DreamDrive/p/6740440.html RemoteMessage.scala trait Remote ...
- Attr的visitNewClass()方法解读
在visitNewClass()方法中有如下注释: We are seeing an anonymous class instance creation.In this case, the class ...
- koa2 接收post参数
koa2接收Post参数由于没有在上下文对象上解析,所以需要用node 原生req解析. 获取到的参数,要注意转码问题. const Koa = require('koa'); const app = ...
- CRM项目完成实现
这两天我们都在写项目的接口与实现的! 今天主要是遇到的问题: 当我在添加新的班级的时候,班级的老师 我需要去判断这个老师是否存在,如果不存在的话,我就要把这个老师添加到学校的员工表中! 我会先判断这个 ...
- Quartz框架多个trigger任务执行出现漏执行的问题分析--转
原文地址:http://blog.csdn.net/dailywater/article/details/51470779 一.问题描述 使用Quartz配置定时任务,配置了超过10个定时任务,这些定 ...
- Silverlight 在ie8 下 报2152 错误
前几天改别人的一个silverlight程序,在项目属性上 选中了 “通过使用应用程序库缓存减小XAP 大小”,编译无错,发布无错误. 放服务器上测试: 站点绑定域名,使用ie9.ie10 都没有问题 ...
- C# 异常语句 跳转语句 while循环 穷举法 迭代法
一 异常语句 ♦ try.....catch....finally 结构形式 try{ 可能会出错的代码语句 如果这里出错了,那么不会在继续下面的代码,而是直接进入catch中处理异常}catc ...
- 入门angularJs笔记手记一
angularjs表达式: ng-init ng-bind ng-app ng-model输入域的值绑定到程序 ng-repeat重复一个HTML元素 自定义指令: <script> va ...
- Listary Pro- 文件浏览与搜索增强的超级神器
Listary 是一款 Windows 文件浏览增强工具,为 Windows 资源管理器增加智能命令.最近文档以及收藏功能.文件小,功能强大.秒杀系统自带搜索功能!! 它是一款非常优秀的 Window ...
- C#里面的事物回滚,解决同步数据插入时出现重复数据
什么是事物回滚: 举个栗子,你在你家的银行分行取钱,取完钱数据要同步,而且可能每个分行都有一个存储这些数据的数据库,分行的这些 存取的记录都需要实时同步,如果你取完500刚好断电了,好嘛,分行可能刚记 ...