如何在 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 让我找到了解决方案。
- 重新缩放设备环境。我没有为 rendert 目标找到像 Resize 这样的方法。
- 从效果输出中制作一个bitmap以再次使用DrawBitmap。我发现不可能这样做。
- 在应用效果之前重新缩放位图。我找不到办法做到这一点。
有人知道这里有什么解决方案吗?
我的问题的一个解决方案是重新缩放渲染目标:
// 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 重新缩放。这对我来说有点违反直觉,但它确实有效。
我按照这个例子创建了一个 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 让我找到了解决方案。
- 重新缩放设备环境。我没有为 rendert 目标找到像 Resize 这样的方法。
- 从效果输出中制作一个bitmap以再次使用DrawBitmap。我发现不可能这样做。
- 在应用效果之前重新缩放位图。我找不到办法做到这一点。
有人知道这里有什么解决方案吗?
我的问题的一个解决方案是重新缩放渲染目标:
// 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 重新缩放。这对我来说有点违反直觉,但它确实有效。