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.