Reputation: 344
I created a Direct2D application following this example: https://github.com/microsoft/Windows-classic-samples/tree/master/Samples/Win7Samples/multimedia/Direct2D/SimpleDirect2DApplication
I managed to show a bitmap in the applications window and the bitmap also rescales when rescaling the window. But now I wanted to apply effects on the bitmap and here comes my problem. The effect is applied like this
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 );
The problem is that after applying the effect, the image data is now in the format of ID2D1Effect. This can be drawn with DrawImage like this:
m_pDeviceContext->DrawImage(gammaTransferEffect);
But I did the rescaling with destinationRectangle
in the function DrawBitmap and there is no equivalent to destinationRectangle
in DrawImage
.
m_pDeviceContext->DrawBitmap(
m_pBitmap,
D2D1::RectF(
0,
0,
renderTargetSize.width,
renderTargetSize.height),
1.0f,
D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR
);
So how can I rescale the bitmap after applying the effect when rescaling the render target? I had some ideas about this, but none led me to a solution.
Somebody an idea what could be a solution here?
Upvotes: 0
Views: 1181
Reputation: 1
Thank you gldhnchn. I had the same problem. In fact I encounter it even without the effect -- RenderTarget->DrawBitmap scales the image as desired, but DeviceContext->DrawImage does not, as demonstrated below. Your fix does the trick.
IMPLEMENT_DYNAMIC(CMyImageCtrl, CStatic)
CMyImageCtrl::CMyImageCtrl()
{
EnableD2DSupport();
CImage image;
image.Load("test_bmap.jpg");
m_pBitmap = new CD2DBitmap(GetRenderTarget(), image.Detach());
}
afx_msg LRESULT CMyImageCtrl::OnDraw2D(WPARAM wParam, LPARAM lParam)
{
CHwndRenderTarget* pRenderTarget = (CHwndRenderTarget*)lParam;
CRect rect;
GetClientRect(rect);
CD2DRectF rectD(rect);
bool bUseRenderTarget = true;
if (bUseRenderTarget) {
// here image scales to fit client
pRenderTarget->DrawBitmap(m_pBitmap, rectD);
} else {
// here image is drawn full native size, does not scale to rect
CComQIPtr<ID2D1DeviceContext> spDeviceContext = pRenderTarget->GetRenderTarget();
spDeviceContext->DrawImage(m_pBitmap->Get(), D2D1::Point2F(0., 0.), rectD);
}
}
Upvotes: 0
Reputation: 344
One solution to my problem is to rescale the render target:
// 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);
Additionally I had to remove my resize
function from the WM_SIZE
message, otherwise my painted bitmap didn't rescale with its window. That was a bit counter intuitive to me, but yay it works.
Upvotes: 0