Win10系列:VC++绘制位图图片

在使用Direct2D绘制图片的过程中,通过IWICImagingFactory工厂接口来得到绘制图片所需要的资源。本小节将介绍如何通过IWICImagingFactory工厂接口得到这些资源,并使用这些资源在应用窗口中绘制一张图片。在20.7.1小节所新建的Direct2DDemo项目基础上,继续介绍绘制图片的实现代码。

在绘制图片之前,首先需要在项目中添加一张图片。右键点击解决方案资源管理器窗口中的项目图标,在弹出的菜单栏中选中"添加",并在"添加"的子菜单栏中选择"现有项",在出现的"添加现有项"窗口中选择名为"Fruit.jpg"的图片文件,单击"添加"按钮将这个图片文件添加到项目中。

将图片添加到项目中以后,接下来打开D2DBasicAnimation.h头文件,并在D2DBasicAnimation类中添加如下的代码:

private:

    //声明成员变量 logoBitmap

    Microsoft::WRL::ComPtr<ID2D1Bitmap> logoBitmap;

    //声明成员变量 logoSize

    D2D_SIZE_F logoSize;

private:

    //获得位图

    void CreateBitmap();

在上面的代码中,使用private关键字声明两个私有的成员变量logoBitmap和logoSize,其中logoBitmap为ID2D1Bitmap类型的指针,logoSize为D2D1_SIZE_F结构体的变量,并使用private关键字声明一个私有的函数CreateBitmap,用于获得位图。

声明了CreateBitmap函数以后,接着打开D2DBasicAnimation.cpp源文件并添加CreateBitmap函数的实现代码,具体代码如下所示:

//得到位图

void D2DBasicAnimation::CreateBitmap()

{

    //声明IWICBitmapDecoder类型的指针

    ComPtr<IWICBitmapDecoder> wicBitmapDecoder;

    DX::ThrowIfFailed(

        wicFactory->CreateDecoderFromFilename(

            L"Fruit.jpg",

            nullptr,

            GENERIC_READ,

            WICDecodeMetadataCacheOnDemand,

            &wicBitmapDecoder

        )

    );

    ComPtr<IWICBitmapFrameDecode> wicBitmapFrame;

    DX::ThrowIfFailed(

        wicBitmapDecoder->GetFrame(0, &wicBitmapFrame)

    );

    ComPtr<IWICFormatConverter> wicFormatConverter;

    //得到IWICFormatConverter类型的对象

    DX::ThrowIfFailed(

    wicFactory->CreateFormatConverter(&wicFormatConverter)

    );

    //初始化wicFormatConverter指针所指向的对象

    DX::ThrowIfFailed(

        wicFormatConverter->Initialize(

            wicBitmapFrame.Get(),

            GUID_WICPixelFormat32bppPBGRA,

            WICBitmapDitherTypeNone,

            nullptr,

            0.0,

            WICBitmapPaletteTypeCustom

        )

    );

    //获取X轴和Y轴方向上的DPI

    double dpiX;

    double dpiY;

    DX::ThrowIfFailed(

        wicFormatConverter->GetResolution(&dpiX, &dpiY)

    );

    //得到ID2D1Bitmap类型的对象

    DX::ThrowIfFailed(

        d2dContext->CreateBitmapFromWicBitmap(

            wicFormatConverter.Get(),

            BitmapProperties(

            PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),static_cast<float>(dpiX),static_cast<float>(dpiY)),

            &logoBitmap

        )

    );

    //得到位图的大小

    logoSize = logoBitmap->GetSize();

}

在上面的代码中,首先声明一个IWICBitmapDecoder类型的指针wicBitmapDecoder,接着以要解码的图片的路径为第一个参数,调用wicFactory指针所指向的对象的CreateDecoderFromFilename函数得到一个IWICBitmapDecoder类型的对象,并使用wicBitmapDecoder指针指向这个对象,此对象表示一个图片解码器用于对图片进行解码。

接下来声明一个IWICBitmapFrameDecode类型的指针wicBitmapFrame,并调用wicBitmapDecoder指针所指向的对象的GetFrame函数得到一个IWICBitmapFrameDecode类型的对象,使用wicBitmapFrame指针指向这个对象。然后声明一个IWICFormatConverter类型的指针wicFormatConverter,并调用wicFactory指针所指向的对象的CreateFormatConverter函数得到一个IWICFormatConverter类型的对象,使用wicFormatConverter指针指向这个对象。接着调用wicFormatConverter指针所指向的对象的Initialize函数来设置图片解码后的格式,将图片的编码方式设置为GUID_WICPixelFormat32bppPBGRA,即图片每个像素使用32位存储,图片透明度设置为0.0,即图片不透明。声明两个double类型的变量dpiX和dpiY,接着调用wicFormatConverter指针所指向的对象的GetResolution函数获取两个浮点数,用于表示位图在X轴和Y轴方向上的DPI值,并分别赋值给dpiX变量和dpiY变量。

接下来调用d2dContext指针所指向的对象的CreateBitmapFromWicBitmap函数得到一个用于表示位图的ID2D1Bitmap类型的对象,使用logoBitmap指针指向这个对象。最后调用logoBitmap指针所指向的对象的GetSize函数得到位图的大小,并赋值给结构体变量logoSize。

添加了CreateBitmap函数的实现代码以后,接下来在D2DBasicAnimation.cpp源文件的CreateDeviceResources函数中分别调用DirectXBase类的CreateDeviceResources函数和上面定义的CreateBitmap函数,代码如下所示:

void D2DBasicAnimation::CreateDeviceResources()

{

    //调用DirectXBase类的CreateDeviceResources函数

    DirectXBase::CreateDeviceResources();

    //得到位图

    CreateBitmap();

}

下面在D2DBasicAnimation.cpp源文件的Render函数中实现图片的绘制,具体代码如下所示:

void D2DBasicAnimation::Render()

{

    //调用BeginDraw函数开始绘图

    d2dContext->BeginDraw();

    //设置应用窗口的背景颜色

    d2dContext->Clear(D2D1::ColorF(D2D1::ColorF::Gray));

    //绘制图片

    d2dContext->DrawBitmap(

        logoBitmap.Get(),

        D2D1::RectF(0.0f, 0.0f, logoSize.width, logoSize.height)

    );

    d2dContext->EndDraw();

}

在上面的代码中,首先调用d2dContext指针所指向的对象的BeginDraw函数开始绘制图片,接着通过d2dContext指针所指向的对象的Clear函数将应用窗口的背景颜色设置为灰色。然后使用d2dContext指针所指向的对象的DrawBitmap函数绘制图片,DrawBitmap函数有两个参数,其中第一个参数是图片的资源,这里将logoBitmap指针所指向的对象作为第一个参数。DrawBitmap函数的第二个参数用来设置绘制图片的大小,这里使用矩形区域作为第二个参数,通过D2D1::RectF函数得到一个矩形区域,并设置该矩形区域的左上角坐标为{0.0f,0.0f},矩形区域的右下角坐标为{ logoSize.width,logoSize.height },其中logoSize.width和logoSize.height分别表示位图的宽和高。最后调用d2dContext指针所指向的对象的EndDraw函数结束图片的绘制操作。

运行Direct2DDemo项目后,将在应用窗口中绘制如图20-18所示的图片。

Win10系列:VC++绘制位图图片

图20-18 Direct2D绘制的图片

上一篇:CCS中CMD文件解析


下一篇:android 应用程序框架