zoukankan      html  css  js  c++  java
  • Direct2D Bitmap操作

    加入位图操作需要引入WIC组件,过程将更复杂:

    View Code
    #include "stdafx.h"
    
    D2D1_COLOR_F const COLOR_BLUE   = { 0.26f, 0.56f, 0.87f, 1.0f };
    D2D1_COLOR_F const COLOR_WHITE    = { 1.0f,  1.0f,  1.0f,  1.0f };
    D2D1_COLOR_F const COLOR_BLACK    = { 0.0f,  0.0f,  0.0f,  1.0f };
    D2D1_COLOR_F const COLOR_YELLOW = { 0.99f, 0.85f, 0.0f,  1.0f };
    D2D1_COLOR_F const COLOR_RED    = { 1.0f,  0.0f,  0.0f,  1.0f };
    
    struct ComInitialize
    {
        ComInitialize()
        {
            HR(CoInitialize(nullptr));
        }
        ~ComInitialize()
        {
            CoUninitialize();
        }
    };
    
    template <typename T>
    void CreateInstance(REFCLSID clsid, ComPtr<T>& ptr)
    {
        ASSERT(!ptr);
        HR(CoCreateInstance(clsid, nullptr, CLSCTX_INPROC_SERVER, 
            __uuidof(T), reinterpret_cast<void **>(ptr.GetAddressOf())));
    }
    
    struct SampleWindow : DesktopWindow<SampleWindow>
    {
        ComPtr<IWICFormatConverter> m_image;
        ComPtr<ID2D1Bitmap> m_bitmap;
        D2D1_RECT_F m_location;
    
        void CreateDeviceIndependentResources()
        {
            ComPtr<IWICImagingFactory> imageFactory;
            CreateInstance(CLSID_WICImagingFactory, imageFactory);
    
            ComPtr<IWICBitmapDecoder> decoder;
            HR(imageFactory->CreateDecoderFromFilename(L"C:\\Users\\Flysha\\Desktop\\cnblogs.gif", 
                nullptr, GENERIC_READ, 
                WICDecodeMetadataCacheOnLoad, decoder.GetAddressOf()));
    
            ComPtr<IWICBitmapFrameDecode> frame;
            HR(decoder->GetFrame(0, frame.GetAddressOf()));
    
            ASSERT(!m_image);
            HR(imageFactory->CreateFormatConverter(m_image.GetAddressOf()));
    
            m_image->Initialize(frame.Get(), GUID_WICPixelFormat32bppPBGRA, 
                WICBitmapDitherTypeNone, nullptr, 0.0, 
                WICBitmapPaletteTypeCustom);
        }
    
        LRESULT MouseMoveHandler(UINT, WPARAM, LPARAM lparam, BOOL&)
        {
            WORD x = LOWORD(lparam);
            WORD y = HIWORD(lparam);
            D2D1_POINT_2U size;
            m_image->GetSize(&size.x, &size.y);
            m_location = RectF(x, y, x + size.x, y + size.y);
            Invalidate();
            return 0;
        }
    
        void CreateDeviceResources()
        {
            HR(m_target->CreateBitmapFromWicBitmap(m_image.Get(), 
                m_bitmap.ReleaseAndGetAddressOf()));
        }
    
        void Draw()
        {
            m_target->Clear(COLOR_BLUE);
            m_target->DrawBitmap(m_bitmap.Get(), m_location, 1.0f, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR);
        }
    };
    
    int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
    {
        ComInitialize com;
        SampleWindow window;
        window.Run();
    }

    示例中加入了图片随鼠标移动而移动的功能。

    可能通过将WIC图片(IWICFormatConverter)转换为D2D图片画笔(ID2D1BitmapBrush),可以设置更多有意思的效果:

    View Code
    #include "stdafx.h"
    
    D2D1_COLOR_F const COLOR_BLUE   = { 0.26f, 0.56f, 0.87f, 1.0f };
    D2D1_COLOR_F const COLOR_WHITE    = { 1.0f,  1.0f,  1.0f,  1.0f };
    D2D1_COLOR_F const COLOR_BLACK    = { 0.0f,  0.0f,  0.0f,  1.0f };
    D2D1_COLOR_F const COLOR_YELLOW = { 0.99f, 0.85f, 0.0f,  1.0f };
    D2D1_COLOR_F const COLOR_RED    = { 1.0f,  0.0f,  0.0f,  1.0f };
    
    struct ComInitialize
    {
        ComInitialize()
        {
            HR(CoInitialize(nullptr));
        }
        ~ComInitialize()
        {
            CoUninitialize();
        }
    };
    
    template <typename T>
    void CreateInstance(REFCLSID clsid, ComPtr<T>& ptr)
    {
        ASSERT(!ptr);
        HR(CoCreateInstance(clsid, nullptr, CLSCTX_INPROC_SERVER, 
            __uuidof(T), reinterpret_cast<void **>(ptr.GetAddressOf())));
    }
    
    struct SampleWindow : DesktopWindow<SampleWindow>
    {
        ComPtr<IWICFormatConverter> m_image;
        ComPtr<ID2D1BitmapBrush> m_brush;
        D2D1_RECT_F m_location;
        
        void CreateDeviceIndependentResources()
        {
            ComPtr<IWICImagingFactory> imageFactory;
            CreateInstance(CLSID_WICImagingFactory, imageFactory);
    
            ComPtr<IWICBitmapDecoder> decoder;
            HR(imageFactory->CreateDecoderFromFilename(L"C:\\Users\\Flysha\\Desktop\\cnblogs.gif", 
                nullptr, GENERIC_READ, 
                WICDecodeMetadataCacheOnLoad, decoder.GetAddressOf()));
    
            ComPtr<IWICBitmapFrameDecode> frame;
            HR(decoder->GetFrame(0, frame.GetAddressOf()));
    
            HR(imageFactory->CreateFormatConverter(m_image.GetAddressOf()));
            HR(m_image->Initialize(frame.Get(), GUID_WICPixelFormat32bppPBGRA, 
                WICBitmapDitherTypeNone, nullptr, 0.0, 
                WICBitmapPaletteTypeCustom));
        }
    
        LRESULT MouseMoveHandler(UINT, WPARAM, LPARAM lparam, BOOL&)
        {
            WORD x = LOWORD(lparam);
            WORD y = HIWORD(lparam);
            D2D1_POINT_2U size;
            m_image->GetSize(&size.x, &size.y);
            m_location = RectF(x, y, x + (FLOAT)size.x, y + (FLOAT)size.y);
            Invalidate();
            return 0;
        }
    
        void CreateDeviceResources()
        {
            ComPtr<ID2D1Bitmap> bitmap;
            HR(m_target->CreateBitmapFromWicBitmap(m_image.Get(), 
                bitmap.GetAddressOf()));
            m_target->CreateBitmapBrush(bitmap.Get(), 
                m_brush.ReleaseAndGetAddressOf());
        }
    
        void Draw()
        {
            m_target->Clear(COLOR_BLUE);
            auto size = m_target->GetSize();
            auto rect = RectF(0.0f, 0.0f, size.width, size.height);
            m_brush->SetExtendModeX(D2D1_EXTEND_MODE_WRAP);
            m_brush->SetExtendModeY(D2D1_EXTEND_MODE_MIRROR);
            m_target->FillRectangle(rect, m_brush.Get());
        }
    };
    
    int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
    {
        ComInitialize com;
        SampleWindow window;
        window.Run();
    }

    除此之外,还可以直接将IWICBitmap保存为图形文件:

    View Code
    #include "stdafx.h"
    
    void SaveAs(ComPtr<IWICImagingFactory>& imageFactory, 
                ComPtr<IWICBitmap> & bitmap, 
                PWSTR filename)
    {
        ComPtr<IStream> file;
        HR(SHCreateStreamOnFileEx(filename, 
            STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 
            FILE_ATTRIBUTE_NORMAL, 
            TRUE, 
            nullptr, 
            file.GetAddressOf()));
    
        ComPtr<IWICBitmapEncoder> encoder;
        HR(imageFactory->CreateEncoder(GUID_ContainerFormatPng, 
            nullptr, 
            encoder.GetAddressOf()));
        HR(encoder->Initialize(file.Get(), WICBitmapEncoderNoCache));
    
        ComPtr<IWICBitmapFrameEncode> frame;
        ComPtr<IPropertyBag2> props;
        HR(encoder->CreateNewFrame(frame.GetAddressOf(), props.GetAddressOf()));
        HR(frame->Initialize(props.Get()));
    
        UINT width, height;
        HR(bitmap->GetSize(&width, &height));
        HR(frame->SetSize(width, height));
    
        WICPixelFormatGUID pixelFormat;
        HR(bitmap->GetPixelFormat(&pixelFormat));
        HR(frame->SetPixelFormat(&pixelFormat));
    
        HR(frame->WriteSource(bitmap.Get(), nullptr));
        HR(frame->Commit());
        HR(encoder->Commit());
    }
    
    int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
    {
        ComInitialize com;
    
        ComPtr<IWICImagingFactory> imageFactory;
        CreateInstance(CLSID_WICImagingFactory, imageFactory);
    
        ComPtr<IWICBitmap> bitmap;
        HR(imageFactory->CreateBitmap(600, 400, 
            GUID_WICPixelFormat32bppPBGRA, 
            WICBitmapCacheOnLoad, 
            bitmap.GetAddressOf()));
    
        ComPtr<ID2D1Factory> factory;
        HR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, factory.GetAddressOf()));
    
        ComPtr<ID2D1RenderTarget> target;
        HR(factory->CreateWicBitmapRenderTarget(bitmap.Get(), 
            RenderTargetProperties(), target.GetAddressOf()));
    
        ComPtr<ID2D1SolidColorBrush> brush;
        HR(target->CreateSolidColorBrush(COLOR_BLUE, brush.GetAddressOf()));
    
        target->BeginDraw();
        target->Clear();
        target->DrawEllipse(Ellipse(Point2F(300.0f, 200.0f), 100.0f, 180.0f), brush.Get(), 10.0f);
        HR(target->EndDraw());
        
        PWSTR filename = L"C:\\users\\flysha\\desktop\\cnblogs.png";
        SaveAs(imageFactory, bitmap, filename);
        ShellExecute(nullptr, nullptr, filename, nullptr, nullptr, SW_SHOWDEFAULT);
    }

  • 相关阅读:
    php单元测试
    git配置本地环境(phpstudy/tortoisegit/git等)
    xp/win7中系统安装memcached服务,卸载memcached服务,以及删除memcached服务
    memcached装、启动和卸载
    如何安装memcached
    三元运算符、逻辑运算符
    移动端页面怎么适配ios页面
    javascript正则表达式——元字符
    一个div添加多个背景图片
    GNU Screen使用入门
  • 原文地址:https://www.cnblogs.com/sdflysha/p/3031741.html
Copyright © 2011-2022 走看看