效果

什麼是 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 ,將 ID2D1Image 格式的內容儲存至編碼影像檔案,例如 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 變數,然後建立 gaussian 模糊 效果。

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

    DrawImage方法必須在ID2DDeviceCoNtext::BeginDrawEndDraw呼叫之間呼叫,就像其他 Direct2D 轉譯作業一樣。 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 相依轉換效果會稍微旋轉點陣圖反時針。

之前
影像之前的 2d affine 效果。
After
影像後的 2d affine 效果。

撰寫影像

某些效果會接受多個輸入,並將其複合成一個產生的影像。

內建複合和算術複合效果提供各種模式,如需詳細資訊,請參閱 複合 主題。 混合效果具有各種可用的 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();

此程式碼會擷取影像並改變色彩,如此處的影像範例所示。

之前
影像之前的色彩矩陣效果。
After
影像之後的色彩矩陣效果。

如需詳細資訊,請參閱 色彩內建效果 一節。

建置效果圖表

您可以將效果鏈結在一起,以轉換影像。 例如,這裡的程式碼會套用陰影和 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 基本影像效果範例

內建效果