Как нарисовать изображение с эффектами, которые изменяют масштаб с его окном в Direct2D - PullRequest
0 голосов
/ 25 октября 2019

Я создал приложение Direct2D, следуя этому примеру: https://github.com/microsoft/Windows-classic-samples/tree/master/Samples/Win7Samples/multimedia/Direct2D/SimpleDirect2DApplication

Мне удалось показать растровое изображение в окне приложений, и растровое изображение также масштабируется при изменении масштаба окна. Но теперь я хотел применить эффекты к растровому изображению, и вот моя проблема. Эффект применяется следующим образом:

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 . Это можно нарисовать с помощью DrawImage следующим образом:

m_pDeviceContext->DrawImage(gammaTransferEffect);

Но я произвел изменение масштаба с помощью destinationRectangle в функции DrawBitmap , и нет эквивалента destinationRectangle in DrawImage.

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

Итак, как я могу изменить масштаб растрового изображения после применения эффекта при изменении масштаба цели рендеринга? У меня были некоторые идеи по этому поводу, но ни одна из них не привела меня к решению.

  1. Масштабируйте контекст устройства. Я не нашел метод, подобный Resize для цели rendert.
  2. Создайте bitmap из вывода эффектов, чтобы снова использовать DrawBitmap. Я не нашел возможности сделать это.
  3. Масштабирование растрового изображения перед применением к нему эффектов. Я не нашел способа сделать это.

Кто-нибудь знает, что может быть решением здесь?

1 Ответ

0 голосов
/ 07 ноября 2019

Одним из решений моей проблемы является изменение масштаба цели рендеринга:

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

Кроме того, мне пришлось удалить функцию resize из сообщения WM_SIZE, в противном случае мое раскрашенное растровое изображение не масштабировалось сего окно. Это было немного противоречиво для меня, но да, это работает.

...