共用方式為


效果

什麼是 Direct2D 效果?

您可以使用 Direct2D 將一或多個高品質的效果套用至影像或一組影像。 效果 API 建置在 Direct3D 11,並利用 GPU 功能進行影像處理。 您可以在效果圖形中鏈結效果,並撰寫或混合效果的輸出。

Direct2D 效果會執行影像工作,例如變更亮度、解除飽和影像,或建立陰影。 效果可以接受零個或多個輸入影像、公開多個控制其作業的屬性,併產生單一輸出影像。

每個效果都會建立由個別轉換組成的內部轉換圖形。 每個轉換都代表單一影像作業。 轉換的主要目的是要容納針對每個輸出圖元執行的著色器。 這些著色器可以包含圖元著色器、頂點著色器、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,將標識碼 2D1Image 格式的內容儲存至編碼的影像檔案,例如 JPEG。
如何將效果套用至基本類型
本主題說明如何將一系列效果套用至 Direct2DDirectWrite 基本類型。
控制效果圖形中的有效位數和數值裁剪
使用 Direct2D 轉譯效果的應用程式必須小心,才能達到與數值精確度相關的所需品質和可預測性層級。

將效果套用至影像

您可以使用 Direct2D 效果 API 將轉換套用至影像。

注意

此範例假設您已經建立ID2D1DeviceContextIWICBitmapSource物件。 如需建立這些對象的詳細資訊,請參閱 如何使用 FilePicker裝置內容將影像載入 Direct2D 效果。

  1. 宣告 ID2D1Effect 變數,然後使用 ID2DDeviceContext::CreateEffect 方法建立位圖來源效果

        ComPtr<ID2D1Effect> bitmapSourceEffect;
    
        DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1BitmapSource, &bitmapSourceEffect));
    
  2. 使用 ID2D1Effect::SetValue,將BitmapSource屬性設定為WIC位圖來源。

            DX::ThrowIfFailed(m_bitmapSourceEffect->SetValue(D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE, m_wicBitmapSource.Get()));
    
  3. 宣告ID2D1Effect變數,然後建立高斯模糊效果。

        ComPtr<ID2D1Effect> gaussianBlurEffect;
    
        DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1GaussianBlur, &gaussianBlurEffect));
    
  4. 設定輸入以接收來自位圖來源效果的影像。 設定 SetValue 方法和標準偏差屬性的模糊量

        gaussianBlurEffect->SetInputEffect(0, bitmapSourceEffect.Get());
    
        DX::ThrowIfFailed(gaussianBlurEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, 6.0f));
    
  5. 使用裝置內容來繪製產生的影像輸出。

        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();
    

    必須在 ID2DDeviceContext::BeginDraw 和 EndDraw 呼叫之間呼叫 DrawImage 方法,就像其他 Direct2D 轉譯作業一樣。 DrawImage 可以擷取影像或效果的輸出,並將其轉譯至目標表面。

空間轉換

Direct2D 提供內建效果,可轉換 2D 和 3D 空間中的影像,以及縮放比例。 縮放和轉換效果提供各種品質等級,例如:最接近的鄰居、線性、立方體、多樣本線性、異向性,以及高品質的立方體。

注意

不過,當您將 Cached 屬性設定為 true 時,非等性模式會在縮放時產生 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 仿射轉換效果會稍微旋轉點陣圖逆時針旋轉。

之前
影像前的 2d 仿射效果。
之後
影像后的 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 物件直接鏈結在一起,這可讓您輕鬆地將多個效果套用至影像,以建立吸引人的視覺效果。

如需詳細資訊,請參閱 如何將效果套用至基本類型

Direct2D 基本影像效果範例

內建效果