Windows 图像处理组件(WIC)读写位深度24位的 bmp 文件

我写了类封装了一下。只是作业需要,缺少错误处理。

cpp 复制代码
#include <wincodec.h>

enum PixColor { B, G, R };

struct ComEnv {
    ComEnv()
    {
        CoInitialize(nullptr);
        CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&fac));
    }

    ~ComEnv()
    {
        fac->Release();
        CoUninitialize();
    }

    static IWICImagingFactory* fac;
}g_comEnvDummy;
IWICImagingFactory* ComEnv::fac;

// 位深度为 24,BGR 格式的 bmp 文件
struct ImgDec {
    ImgDec(LPCWSTR fname)
    {
        ComEnv::fac->CreateDecoderFromFilename(fname, nullptr, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &dec);
        dec->GetFrame(0, &fram);
        ComEnv::fac->CreateBitmapFromSource(fram, WICBitmapCacheOnDemand, &bmp);
        bmp->GetSize(&w, &h);
        WICRect rc = { .X = 0, .Y = 0, .Width = (INT)w, .Height = (INT)h };
        bmp->Lock(nullptr, WICBitmapLockRead, &lck);
        lck->GetStride(&stride);
        lck->GetDataPointer(&bufsiz, &v);
    }

    BYTE& operator()(int i, int j, PixColor c)
    {
        BYTE* row = v + (UINT64)i * stride;
        BYTE* p = row + 3ull * j;
        return p[c];
    }

    void saveAs(LPCWSTR newName)
    {
        IWICStream* str;
        ComEnv::fac->CreateStream(&str);
        str->InitializeFromFilename(newName, GENERIC_WRITE);

        IWICBitmapEncoder* enc;
        ComEnv::fac->CreateEncoder(GUID_ContainerFormatBmp, nullptr, &enc);
        enc->Initialize(str, WICBitmapEncoderNoCache);

        IWICBitmapFrameEncode* fram;
        IPropertyBag2* opt = nullptr;
        enc->CreateNewFrame(&fram, &opt); // opt 既是入参也是出参
        // 现在 opt 是默认选项

        fram->Initialize(opt);
        fram->SetSize(w, h);
        WICPixelFormatGUID fmt = GUID_WICPixelFormat24bppBGR;
        fram->SetPixelFormat(&fmt);
        fram->WritePixels(h, stride, h * stride, v);

        fram->Commit();
        enc->Commit();

        fram->Release();
        opt->Release();
        enc->Release();
        str->Release();
    }

    ~ImgDec()
    {
        lck->Release();
        bmp->Release();
        fram->Release();
        dec->Release();
    }

    IWICBitmapDecoder* dec;
    IWICBitmapFrameDecode* fram;
    IWICBitmap* bmp;
    IWICBitmapLock* lck;
    UINT w, h;
    UINT stride;
    UINT bufsiz;
    BYTE* v;
};
相关推荐
WL学习笔记19 小时前
使用string类
c++·后端·string类
xxxiugou12319 小时前
链表算法题精讲:从两数相加到K组翻转
数据结构·c++·算法·链表
HAPPY酷19 小时前
C++ 自定义内存池优化点云处理:从裸指针到 RAII 自动回收
开发语言·c++
paul_chen2120 小时前
解决Windows “此电脑”出现两个“图片”文件夹的问题
windows
zhangdaliangmvp20 小时前
快速排序的学习理解:从基础分治到三路划分优化
c++·学习·算法
cu14321 小时前
细谈IT6563的具体功能与其应用
c语言·c++·单片机·嵌入式硬件
SoulRoar.21 小时前
在 Windows 上面部署 StartLux
windows·大模型·startlux
布莱克60521 小时前
C++ 内存泄漏全解析:常见场景、成因与规避实践
开发语言·c++·内存泄露
爱吃提升21 小时前
DirectX修复工具安装配置教程-运行权限检测修复与运行库更新参数速查
windows
jimy121 小时前
lvalue、xvalue、prvalue(一):三者的分类
开发语言·c++