0

My sequencer includes support for video, so I want to display bitmaps in the editor. The idea is to have a WIC bitmap, process it with some filters and then render it with Direct2D.

When I load the WIC bitmap from an image, everything is good. I use IWICImagingFactory::CreateDecoderFromFilename() , GetFrame(), and a converter to GUID_WICPixelFormat32bppPBGRA. I am able to display the bitmap with Direct2D ID2D1RenderTarget::CreateBitmapFromWicBitmap(), and I also am able to save the WIC to a jpg (error checking removed, all calls return S_OK):

// Create and initialize WIC Bitmap Encoder.
CComPtr<IWICBitmapEncoder> wicBitmapEncoder;
auto hr = WbF()->CreateEncoder(
    wicFormat,
    nullptr,    // No preferred codec vendor.
    &wicBitmapEncoder
);

wicBitmapEncoder->Initialize(&vs,WICBitmapEncoderNoCache);

// Create and initialize WIC Frame Encoder.
CComPtr<IWICBitmapFrameEncode> wicFrameEncode;
wicBitmapEncoder->CreateNewFrame(&wicFrameEncode,nullptr);

wicFrameEncode->Initialize(nullptr);
wicFrameEncode->SetSize(W, H);
WICPixelFormatGUID gg;
gg = GUID_WICPixelFormat32bppPBGRA;
wicFrameEncode->SetPixelFormat(&gg);

wicFrameEncode->WriteSource(wic, NULL);
wicFrameEncode->Commit();
wicBitmapEncoder->Commit();

The weird thing is when I create the WIC bitmap from raw bytes. This can happen when reading a video which I get a frame using Media Foundation IMFSourceReader::ReadSample method and this returns me a raw bytes frame (converted to RGBA with Media Foundation's converters).

This time Direct2D still works and WIC is still created;

CComPtr<IWICBitmap> wb;
auto hr = WbF()->CreateBitmapFromMemory(width, height, GUID_WICPixelFormat32bppPBGRA, Width * 4, raw.size() * sizeof(DWORD), (BYTE*)raw.data(), &wb);

Direct2D succeeds in rendering the image, so the buffer is valid. Howver the code above does not work. It results in a black JPG file.

Also, this WIC cannot be used in Direct2D effect processing. When I pass it to effect mechanism:

    CComPtr<ID2D1Effect> eff;
    m_d2dContext->CreateEffect(CLSID_D2D1Sepia, &eff);

    // Input bitmap
    CComPtr<ID2D1Effect> bitmapSourceEffect;
    m_d2dContext->CreateEffect(CLSID_D2D1BitmapSource, &bitmapSourceEffect);

    bitmapSourceEffect->SetValue(D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE, wic);
    eff->SetInputEffect(0, bitmapSourceEffect);

    eff->SetValue(D2D1_SEPIA_PROP_INTENSITY, 0.5f);
    eff->SetValue(D2D1_SEPIA_PROP_ALPHA_MODE, D2D1_ALPHA_MODE_PREMULTIPLIED);

    m_d2dContext->BeginDraw();
    D2D1_COLOR_F black = { 0,0,0,1.0f };
    ct->d->m_d2dContext->Clear(black);
    ct->d->m_d2dContext->DrawImage(eff);
    ct->d->m_d2dContext->EndDraw();

The above code draws nothing (only the black bg). When the WIC is loaded from an image, this code successfully processes the Wic image.

What could be wrong?

Edit: Ok this is really weird. I get the video samples in a MFVideoFormat_ARGB32 format.

When I use CreateBitmapFromMemory with GUID_WICPixelFormat32bppBGRA, the image can be saved to a stream correctly, but then Direct2D displays an empty image (the image is converted with IWICFormatConverter to GUID_WICPixelFormat32bppPBGRA, ID2D1REnderTarget::CreateBitmapFromWicBitmap returns S_OK but the bitmap is empty).

When I use CreateBitmapFromMemory with GUID_WICPixelFormat32bppPBGRA , the image cannot be saved to a stream (it saves an empty image), but this is correctly displayed by Direct2D.

Michael Chourdakis
  • 10,345
  • 3
  • 42
  • 78

0 Answers0