效果
什么是 Direct2D 效果?
可以使用 Direct2D 将一个或多个高质量效果应用于图像或一组图像。 效果 API 基于 Direct3D 11 构建,并利用 GPU 功能进行图像处理。 可以在效果图中链接效果,并组合或混合效果的输出。
Direct2D 效果执行图像任务,例如更改亮度、使图像去饱和或创建投影。 效果可以接受零个或多个输入图像,公开控制其操作的多个属性,并生成单个输出图像。
每个效果创建由单个转换组成的内部转换图。 每个转换表示单个图像操作。 转换main目的是容纳为每个输出像素执行的着色器。 这些着色器可以包括像素着色器、顶点着色器、GPU 的混合阶段和计算着色器。
可以使用自定义效果 API 创建的 Direct2D内置效果 和 自定义效果 都以这种方式工作。
有一系列来自类别的 内置效果 ,如此处的类别。 有关完整列表,请参阅 内置效果 部分。
你可以将效果应用于任何位图,包括:Windows 图像处理组件 (WIC) 加载的图像、Direct2D 绘制的基元、来自DirectWrite的文本或 Direct3D 渲染的场景。
使用 Direct2D 效果,可以编写可用于应用程序的效果。 自定义效果框架允许使用 GPU 功能,例如像素着色器、顶点着色器和混合单元。 还可以在自定义效果中包含其他内置或自定义效果。 用于生成自定义效果的框架与用于创建 Direct2D 内置效果的框架相同。 Direct2D 效果创作 API 提供了一组用于创建和注册效果的接口。
更多效果主题
本主题的其余部分介绍了 Direct2D 效果的基础知识,例如将效果应用于图像。 此处的表包含有关效果的其他主题的链接。
主题 | 说明 |
---|---|
效果着色器链接 |
Direct2D 使用称为效果着色器链接的优化,它将多个效果图呈现传递合并到一个通道中。 |
自定义效果 |
演示如何使用标准 HLSL 编写自己的自定义效果。 |
如何使用 FilePicker 将图像加载到 Direct2D 效果中 |
演示如何使用 Windows::Storage::P ickers::FileOpenPicker 将图像加载到 Direct2D 效果中。 |
如何将 Direct2D 内容保存到图像文件 |
本主题演示如何使用 IWICImageEncoder 以 ID2D1Image 的形式将内容保存到 JPEG 等编码图像文件。 |
如何将效果应用于基元 |
本主题演示如何对 Direct2D 和DirectWrite基元应用一系列效果。 |
控制效果图中的精度和数值剪裁 |
使用 Direct2D 呈现效果的应用程序必须小心,才能在数值精度方面达到所需的质量和可预测性级别。 |
将效果应用于图像
可以使用 Direct2D 效果 API 将转换应用于图像。
注意
此示例假定已创建 ID2D1DeviceContext 和 IWICBitmapSource 对象。 有关创建这些对象的详细信息,请参阅如何使用 FilePicker 和设备和设备上下文将图像加载到 Direct2D 效果中。
声明 ID2D1Effect 变量,然后使用 ID2DDeviceContext::CreateEffect 方法创建位图源效果。
ComPtr<ID2D1Effect> bitmapSourceEffect; DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1BitmapSource, &bitmapSourceEffect));
使用 ID2D1Effect::SetValue 将 BitmapSource 属性设置为 WIC 位图源。
DX::ThrowIfFailed(m_bitmapSourceEffect->SetValue(D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE, m_wicBitmapSource.Get()));
声明 ID2D1Effect 变量,然后创建 高斯模糊 效果。
ComPtr<ID2D1Effect> gaussianBlurEffect; DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1GaussianBlur, &gaussianBlurEffect));
设置输入以从位图源效果接收图像。 设置 SetValue 方法和标准偏差属性的模糊量。
gaussianBlurEffect->SetInputEffect(0, bitmapSourceEffect.Get()); DX::ThrowIfFailed(gaussianBlurEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, 6.0f));
使用设备上下文绘制生成的图像输出。
m_d2dContext->BeginDraw(); m_d2dContext->Clear(D2D1::ColorF(D2D1::ColorF::CornflowerBlue)); // Draw the blurred image. m_d2dContext->DrawImage(gaussianBlurEffect.Get()); HRESULT hr = m_d2dContext->EndDraw();
与其他 Direct2D 呈现操作一样,必须在 ID2DDeviceContext::BeginDraw 和 EndDraw 调用之间调用 DrawImage 方法。 DrawImage 可以拍摄图像或效果的输出,并将其呈现到目标图面。
空间转换
Direct2D 提供可在 2D 和 3D 空间中转换图像以及缩放的内置效果。 缩放和变换效果提供各种质量级别,例如:最近邻、线性、立方、多样本线性、各向异性和高质量立方体。
注意
各向异性模式在缩放时生成 mipmap,但是,如果在输入到转换的效果上将 Cached 属性设置为 true,则不会每次为足够小的图像生成 mipmap。
ComPtr<ID2D1Effect> affineTransformEffect;
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D12DAffineTransform, &affineTransformEffect));
affineTransformEffect->SetInput(0, bitmap.Get());
D2D1_MATRIX_3X2_F matrix = D2D1::Matrix3x2F(0.9f, -0.1f, 0.1f, 0.9f, 8.0f, 45.0f);
DX::ThrowIfFailed(affineTransformEffect->SetValue(D2D1_2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX, matrix));
m_d2dContext->BeginDraw();
m_d2dContext->DrawImage(affineTransformEffect.Get());
m_d2dContext->EndDraw();
这种使用 2D 仿射转换效果会稍微逆时针旋转位图。
之前 |
---|
之后 |
合成图像
某些效果接受多个输入,并将其合成为一个生成的图像。
内置的复合效果和算术复合效果提供各种模式,有关详细信息,请参阅 复合 主题。 混合效果有多种可用的 GPU 加速模式。
ComPtr<ID2D1Effect> compositeEffect;
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1Composite, &compositeEffect));
compositeEffect->SetInput(0, bitmap.Get());
compositeEffect->SetInput(1, bitmapTwo.Get());
m_d2dContext->BeginDraw();
m_d2dContext->DrawImage(compositeEffect.Get());
m_d2dContext->EndDraw();
复合效果根据指定的模式以各种不同方式组合图像。
像素调整
有一些内置的 Direct2D 效果可用于更改像素数据。 例如,颜色矩阵效果可用于更改图像的颜色。
ComPtr<ID2D1Effect> colorMatrixEffect;
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1ColorMatrix, &colorMatrixEffect));
colorMatrixEffect->SetInput(0, bitmap.Get());
D2D1_MATRIX_5X4_F matrix = D2D1::Matrix5x4F(0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0);
DX::ThrowIfFailed(colorMatrixEffect->SetValue(D2D1_COLORMATRIX_PROP_COLOR_MATRIX, matrix));
m_d2dContext->BeginDraw();
m_d2dContext->DrawImage(colorMatrixEffect.Get());
m_d2dContext->EndDraw();
此代码采用图像并更改颜色,如此处的示例图像所示。
之前 |
---|
之后 |
有关详细信息,请参阅 颜色内置效果 部分。
生成效果图
可以将效果链接在一起以转换图像。 例如,此处的代码应用阴影和 2D 转换,然后将结果组合在一起。
ComPtr<ID2D1Effect> shadowEffect;
ComPtr<ID2D1Effect> affineTransformEffect;
ComPtr<ID2D1Effect> compositeEffect;
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1Shadow, &shadowEffect));
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D12DAffineTransform, &affineTransformEffect));
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1Composite, &compositeEffect));
shadowEffect->SetInput(0, bitmap.Get());
affineTransformEffect->SetInputEffect(0, shadowEffect.Get());
D2D1_MATRIX_3X2_F matrix = D2D1::Matrix3x2F::Translation(20, 20));
affineTransformEffect->SetValue(D2D1_2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX, matrix);
compositeEffect->SetInputEffect(0, affineTransformEffect.Get());
compositeEffect->SetInput(1, bitmap.Get());
m_d2dContext->BeginDraw();
m_d2dContext->DrawImage(compositeEffect.Get());
m_d2dContext->EndDraw();
下面是结果。
效果采用 ID2D1Image 对象作为输入。 可以使用 ID2D1Bitmap ,因为接口派生自 ID2D1Image。 还可以使用 ID2D1Effect::GetOutput 获取 ID2D1Effect 对象的输出作为 ID2D1Image ,或使用 SetInputEffect 方法转换输出。 在大多数情况下,效果图由直接链接在一起的 ID2D1Effect 对象组成,因此可以轻松地将多个效果应用于图像以创建引人注目的视觉对象。
有关详细信息 ,请参阅如何将效果应用于基元 。
相关主题
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈