C++系列——Direct2D进行图片处理

C++系列——Direct2D图片处理

01 前言

图片处理工具多如牛毛了,自不必说。主要是应对需要批量处理的场景,所以不如手搓。已经试过直接用C#封装好的库System.Drawing,挺好的,就是过了一段时间感觉这速度有点受不了。于是转用C++,结合GDI+又手搓了一个。因为部分代码与C#版本类似(C#底层用的还是GDI),很快也搞好了。
嗯~~ 这下舒服了。随着效率的提高,我以为可以快乐的摸鱼了。省下来的时间里,突然想到——有没有可能利用上GPU的性能再提高一下?于是与Direct2D偶遇了,有人说这玩意比GDI+更快,还可以利用GPU的优势。什么?总以为这玩意就是做游戏开发的,这辈子可能都接触不到的……
于是,新的活又来了——继续搓。
因为需求只是想简单的做图片处理,比如复制图片,然后加点文字、形状等等,然后保存输出。但是似乎这么玩的人比较少(或者可能是用Direct2D的人比较少),资料比较少。没办法只能结合官方的文档慢慢踩坑了。
第一步,我只想简单地从磁盘读取一个PNG图片,然后再画一个矩形,然后再另存为一张图。就这么一个简单的需求,不需要显示到窗口什么的,就单纯的图片处理,都没找到一个比较完整可用的例子(我菜我承认 )。
由于半桶水的水平,摸索了大半天才搞出来一个例子,供学习参考。

02 正文

开发环境:

Windows 11 64 bit
Microsoft Visual Studio Community 2022
C++ 14

VS编辑器,怎么创建项目不用多说了。
就直接写在主文件中。代码如下:

// ImgTool.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <windows.h>
#include <d2d1.h>
#include <d2d1_1.h>
#include <wincodec.h>


//表示链接XXXX.lib这个库。
//和在工程设置里写上链入wpcap.lib的效果一样(两种方式等价,或说一个隐式一个显式调用)
//不过这种方法写的 程序别人在使用你的代码的时候就不用再设置工程settings了。
//告诉连接器连接的时候要找XXX.lib,这样你就不用在linker的lib设置里指定这个lib了。
#pragma comment(lib, "d2d1.lib")
#pragma comment(lib, "windowscodecs.lib")


using namespace std;

/// <summary>
/// 释放 COM 接口指针
/// https://learn.microsoft.com/zh-cn/windows/win32/medfound/saferelease
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="ppT"></param>
template <class T> void SafeRelease(T** ppT)
{
   
    if (*ppT)
    {
   
        (*ppT)->Release();
        *ppT = NULL;
    }

}

/// <summary>
/// 导入图片,转换成direct2d的图像对象:ID2D1Bitmap
/// </summary>
/// <param name="pRenderTarget"></param>
/// <param name="pIWICFactory"></param>
/// <param name="resourceName"></param>
/// <param name="ppBitmap"></param>
/// <returns></returns>
HRESULT LoadResourceBitmap(
    ID2D1RenderTarget* pRenderTarget,
    IWICImagingFactory* pIWICFactory,
    PCWSTR resourceName,
    ID2D1Bitmap** ppBitmap
)
{
   
    IWICBitmapDecoder* pDecoder = NULL;
    IWICBitmapFrameDecode* pSource = NULL;
    IWICFormatConverter* pConverter = NULL;


    //直接从文件,比fromStream方便一点,不需要处理那么多步
    HRESULT hr = pIWICFactory->CreateDecoderFromFilename(
        resourceName, NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &pDecoder
    );
   
    if (SUCCEEDED(hr))
    {
   
        // Create the initial frame.
        hr = pDecoder->GetFrame(0, &pSource);
    }
    else {
   
        std::cout << "pDecoder->GetFrame fail..." << std::endl
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值