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):接受 ...
随机推荐
- (转)python之from_bytes、to_bytes
原文:https://blog.csdn.net/PYTandFA/article/details/78741339 https://python3-cookbook.readthedocs.io/z ...
- Android开发中实现https校验
在安卓开发中需要自己写代码实现校验公钥的功能 当然, 如果是自己服务器,就不用校验, 如果是别人的服务器,比如银行,就需要校验 在这里, 小编采用从github上下载的开源框架实现,在开源框架中添加 ...
- Linux安装codis
codis用go语言开发的,安装前记得先安装go开发环境,Linux安装go语言开发包 前提条件:记得安装git,否则无法下载go语言开发包 1.建立一个go语言的工作目录创建目录:sudo mkdi ...
- css text-align文字两端对齐
text-align:start | end | left | right | center | justify | match-parent | justify-all justify: 内容两端对 ...
- 【IT笔试面试题整理】给定二叉树,给每层生成一个链表
[试题描述]定义一个函数,给定二叉树,给每层生成一个链表 We can do a simple level by level traversal of the tree, with a slight ...
- hibernate辅助类含分页
package com.cy.utils; import java.io.Serializable; import java.util.Iterator; import java.util.List; ...
- C++ STL 学习
/* algorithm-算法 */ .copy() //此函数用在vector中只做拷贝使用,它不能让vector有自动扩充作用.如果vector的容量小于它拷贝的数据量将会报错. /* itera ...
- Python制作回合制手游外挂简单教程(上)
引入: 每次玩回合制游戏的时候,反反复复的日常任务让人不胜其烦 玩问道的时候,我们希望能够自动刷道,玩梦幻希望能自动做师门.捉鬼等等 说明: 该外挂只能模拟鼠标键盘操作,并不能修改游戏数据 我这里使用 ...
- Linux后台运行java的jar包
Linux 运行jar包命令如下: 方式一 特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 那如何让窗口不锁定? 方式二 java -jar shareniu. ...
- Java maven项目的小随笔
1.web.xml里面有filter拦截设置,注意. 2.编译之后,网页中读取资源的路径是apache-tomcat/wtpwebapps/..,若该路径下没有相应资源,则报404错误.