如何在 direct2d 中绘制具有随其 window 重新缩放的效果的图像

How to draw a image with effects that rescales with it's window in direct2d

我按照这个例子创建了一个 Direct2D 应用程序:https://github.com/microsoft/Windows-classic-samples/tree/master/Samples/Win7Samples/multimedia/Direct2D/SimpleDirect2DApplication

我设法在应用程序 window 中显示位图,并且位图在重新缩放 window 时也会重新缩放。但是现在我想在位图上应用效果,我的问题来了。效果是这样应用的

hr = m_pRenderTarget->QueryInterface( __uuidof(ID2D1DeviceContext), (void**)&m_pDeviceContext );
m_pDeviceContext->CreateEffect( CLSID_D2D1GammaTransfer, &gammaTransferEffect );
gammaTransferEffect->SetInput( 0, m_pBitmap );
gammaTransferEffect->SetValue( D2D1_GAMMATRANSFER_PROP_RED_AMPLITUDE, 4.0f );

问题是在应用效果后,图像数据现在是 ID2D1Effect. This can be drawn with DrawImage 的格式,如下所示:

m_pDeviceContext->DrawImage(gammaTransferEffect);

但我在函数 DrawBitmap 中使用 destinationRectangle 进行了重新缩放,并且 DrawImage 中没有等同于 destinationRectangle 的函数。

m_pDeviceContext->DrawBitmap(
            m_pBitmap,
            D2D1::RectF(
                0,
                0,
                renderTargetSize.width,
                renderTargetSize.height),
            1.0f,
            D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR
        );

那么在重新缩放渲染目标时应用效果后如何重新缩放位图?我对此有一些想法,但 none 让我找到了解决方案。

  1. 重新缩放设备环境。我没有为 rendert 目标找到像 Resize 这样的方法。
  2. 从效果输出中制作一个bitmap以再次使用DrawBitmap。我发现不可能这样做。
  3. 在应用效果之前重新缩放位图。我找不到办法做到这一点。

有人知道这里有什么解决方案吗?

我的问题的一个解决方案是重新缩放渲染目标:

// Retrieve the size of the render target.
D2D1_SIZE_F renderTargetSize = m_pRenderTarget->GetSize();
// calculate scale factors
float scale_x = renderTargetSize.width / _bitmapSource.width;
float scale_y = renderTargetSize.height / _bitmapSource.height;
// scale render target
m_pRenderTarget->SetTransform(
    D2D1::Matrix3x2F::Scale(
        D2D1::Size( scale_x, scale_y ),
        D2D1::Point2F( 0.0f, 0.0f ))
);
hr = m_pRenderTarget->QueryInterface( __uuidof(ID2D1DeviceContext), (void**)&m_pDeviceContext );
m_pDeviceContext->CreateEffect( CLSID_D2D1GammaTransfer, &gammaTransferEffect );
gammaTransferEffect->SetInput( 0, m_pBitmap );
gammaTransferEffect->SetValue( D2D1_GAMMATRANSFER_PROP_RED_AMPLITUDE, 4.0f );
m_pDeviceContext->DrawImage(gammaTransferEffect);

此外,我必须从 WM_SIZE 消息中删除我的 resize 函数,否则我绘制的位图不会随其 window 重新缩放。这对我来说有点违反直觉,但它确实有效。