C++ Need to convert BYTE * data from my Webcam to ID2D1Image * for ID2D1Effect::SetInput method for crossfade effect

  c++, direct2d, mfc, winapi

I am working on a C++/CLI program using Win32 Media Foundation and Windows Forms. I was able to get my USB webcams data into a BYTE* array in C++ and pass the data to my managed code to display in a picturebox.

Now I want to be able to do a crossfade between 2 cameras, but the code I wrote in C++ doesn’t do it smoothly. I am experimenting with the Direct2D ID2D1 crossfade effect to see if it would look any better.

Apparently the ID2D1Effect interface ID2D1Effect::SetInput method wants the data as a ID2D1Image*. I could really use some help to figure out how to convert a frame of RGB32 webcam data pointed to by a BYTE* pointer to ID2D1Image*.

Here is what I have so far:

CrossFade.h
#pragma once

#include <comip.h>
#include <atlcomcli.h>
#include <d2d1_1.h>
#include <d2d1effects_2.h>


#pragma comment(lib,"d2d1.lib")
#pragma comment(lib,"dxguid.lib")

class CrossFade
{

    ID2D1Factory* pD2DFactory;
    ID2D1HwndRenderTarget* pRT;

public:

    //Data in my webcam class
    BYTE * srcData = nullptr;
    BYTE * dstData = nullptr;

    //Methods

    CrossFade(HWND hwndPgm, int iWidth, int iHeight);

    ~CrossFade();

    void Draw(ID2D1Image* pBitmapSrc, ID2D1Image* pBitmapDest, float dWeight);

};



CrossFade.cpp

#include "CrossFade.h"

CrossFade::CrossFade(HWND hwndPgm, int iWidth, int iHeight)
{

   HRESULT hr = S_OK;
   pD2DFactory = NULL;
   pRT = NULL;

   D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory);

   //hwndPgm references the picturbox handle. I may need to change this to a panel handle according to some posts.

   hr = pD2DFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(), 

   D2D1::HwndRenderTargetProperties(hwndPgm, D2D1::SizeU(iWidth, iHeight)), &pRT);

}

CrossFade::~CrossFade()
{

}



void CrossFade::Draw(float dWeight)
{

    if (srcData == nullptr || dstData == nullptr) return; //Data not ready

    //I know this is incorrect, I'm just trying to indicate I need the BYTE* data to be converted to ID2D1Image* data
    ID2D1Image* pBitmapSrc = srcData;
    ID2D1Image* pBitmapDest = dstData;
    
    CComQIPtr<ID2D1DeviceContext> spDeviceContext = pRT;

    CComPtr<ID2D1Effect> spCrossFadeEffect;
    spDeviceContext->CreateEffect(CLSID_D2D1CrossFade, &spCrossFadeEffect);

    // set source and destination bitmaps
    spCrossFadeEffect->SetInput(0, pBitmapSrc);
    spCrossFadeEffect->SetInput(1, pBitmapDest);

    spCrossFadeEffect->SetValue(D2D1_CROSSFADE_PROP_WEIGHT, static_cast<FLOAT>(dWeight));

    spDeviceContext->DrawImage(spCrossFadeEffect);

}

Once this is working, I would also like to figure out how to use animation to create a smooth transition. if I include afxanimationcontroller.h I get an error WINDOWS.H is already included. MFC apps must not #include<Windows.h>.

Is there something other than MFC I could use to animate the crossfade? I’m not using MFC otherwise.

Source: Windows Questions C++

LEAVE A COMMENT