前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WPF 对接 Vortice 调用 WIC 加载图片

WPF 对接 Vortice 调用 WIC 加载图片

作者头像
林德熙
发布2023-05-16 20:19:45
3860
发布2023-05-16 20:19:45
举报
文章被收录于专栏:林德熙的博客

本文将告诉大家如何通过 Vortice 库从底层的方式使用 WIC 层加载本地图片文件,解码为 IWICBitmap 图片,然后将 IWICBitmap 图片交给 WPF 进行渲染

本文的前置博客:WPF 对接 Vortice 调用 D2D 使用 IWICBitmap 离屏渲染

先集中精力到如何通过 WIC 层加载本地文件为图片上,本文的所有代码都可以在本文末尾获取

下面介绍比较通用的做法进行加载图片文件。按照惯例,先创建出 IWICImagingFactory 对象,如以下代码

代码语言:javascript
复制
  using Vortice.WIC;

      using var wicImagingFactory = new IWICImagingFactory();

通过 using var 的方式可以减少大量的 Dispose 代码,将自动在方法结束之前调用 Dispose 方法释放资源。值得一提的是作为非常底层基础的 Vortice 框架,在使用 对接时,各个创建出来的对象资源都需要关注一下,基本都需要自己手工释放

通过 CreateStream 方法从文件创建为 IWICStream 对象,如此即可方便后续的图片加载

代码语言:javascript
复制
        var imageFilePath = System.IO.Path.GetFullPath("Image.png");
        using var wicStream = wicImagingFactory.CreateStream(imageFilePath, FileAccess.Read);

还请将以上代码的 imageFilePath 替换为你实际的图片文件

在获取到 IWICStream 之后,想要加载图片,就需要用到图片解码器。解码器本身可以通过 IWICImagingFactory 从 IWICStream 里创建,代码如下

代码语言:javascript
复制
        using var decoder = wicImagingFactory.CreateDecoderFromStream(wicStream, DecodeOptions.CacheOnLoad/*参数和 WPF 一样*/);

创建出来的解码器自动进行解码,如果解码失败,比如图片文件损坏或者对应图片格式找不到解码器等,都会抛出异常炸掉。异常是对应有 WIC 的错误码信息的,如比较常见的图片损坏的如下异常

代码语言:javascript
复制
SharpGen.Runtime.SharpGenException:“HRESULT: [0x88982F50], Module: [Vortice.Direct2D1], ApiCode: [WINCODEC_ERR_COMPONENTNOTFOUND/Componentnotfound], Message: [无法找不到组件。
]”

错误码信息可以到 Codec Error Codes - Win32 apps Microsoft Learn 官方文档了解更多信息

从解码器获取到解码的 IWICBitmap 图片,可以使用 GetFrame 方法。这个方法需要传入参数,因为解码器将可以解码出图片,对于动态图片可以解析出多张图片出来,对于静态图片只能解析出一张。对于静态图片(区别于 gif 等动态图片)只须取首个,也就是常用的就是传入 0 就好

代码语言:javascript
复制
        using var imageFrame = decoder.GetFrame(0);

拿到 IWICBitmapFrameDecode 类型的 imageFrame 对象即可通过 CreateBitmapFromSource 创建 IWICBitmap 图片

代码语言:javascript
复制
        IWICBitmap wicBitmap = wicImagingFactory.CreateBitmapFromSource(imageFrame, BitmapCreateCacheOption.CacheOnLoad);

如此即可拿到 IWICBitmap 对象,再通过 上一篇博客 提供的方法即可在 WPF 显示

以下是加载本地图片作为 IWICBitmap 的所有代码

代码语言:javascript
复制
    private static IWICBitmap OpenFileAsWICBitmap()
    {
        using var wicImagingFactory = new IWICImagingFactory();
        var imageFilePath = System.IO.Path.GetFullPath("Image.png");
        using var wicStream = wicImagingFactory.CreateStream(imageFilePath, FileAccess.Read);
        using var decoder = wicImagingFactory.CreateDecoderFromStream(wicStream, DecodeOptions.CacheOnLoad/*参数和 WPF 一样*/);
        // 解码器将可以解码出图片,对于动态图片可以解析出多张图片出来,对于静态图片只能解析出一张
        // 对于静态图片(区别于 gif 等动态图片)只须取首个
        using IWICBitmapFrameDecode imageFrame = decoder.GetFrame(0);

        IWICBitmap wicBitmap = wicImagingFactory.CreateBitmapFromSource(imageFrame, BitmapCreateCacheOption.NoCache);

        return wicBitmap;
    }

其中创建 IWICStream 这一步可以省略,通过 CreateDecoderFromFileName 即可从文件创建解码器,更新的代码如下

代码语言:javascript
复制
    private static IWICBitmap OpenFileAsWICBitmap()
    {
        using var wicImagingFactory = new IWICImagingFactory();
        var imageFilePath = System.IO.Path.GetFullPath("Image.png");
        using var decoder = wicImagingFactory.CreateDecoderFromFileName(imageFilePath);
        // 解码器将可以解码出图片,对于动态图片可以解析出多张图片出来,对于静态图片只能解析出一张
        // 对于静态图片(区别于 gif 等动态图片)只须取首个
        using IWICBitmapFrameDecode imageFrame = decoder.GetFrame(0);

        IWICBitmap wicBitmap = wicImagingFactory.CreateBitmapFromSource(imageFrame, BitmapCreateCacheOption.NoCache);
        return wicBitmap;
    }

只是常用的情况下会考虑一些通用性,才使用 IWICStream 对象

本文的代码放在githubgitee 欢迎访问

可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

代码语言:javascript
复制
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 11ede4eb7cb224fe0f561de16d86874a4b71cec2

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码

代码语言:javascript
复制
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 11ede4eb7cb224fe0f561de16d86874a4b71cec2

获取代码之后,进入 WpfVorticeWicTest 文件夹

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档