0

I'm trying to convert an HBITMAP to an IWICBitmap, and I'm having quite a bit of trouble. I found the function:

CreateBitmapFromHBITMAP();

but I can't get it to work. Here is how I am using it:

void camera_avtcam_ex_t::GrabAsyncFrame(ULONG frameId, IWICImagingFactory* pWicFactory, IWICBitmap** outputBitmap, bool* pAbort )
{

        QueueCamFrame();
        HBITMAP transferbitmap;
        GetFeatureAndRunAcquisitionStart(transferbitmap); //returns transferbitmap 
                                                          //as a valid HBITMAP
       //This HBITMAP works, I can save it to a file and/or print 
       //it to the screen and the image is displayed properly

        pWicFactory->CreateBitmapFromHBITMAP(transferbitmap, NULL, WICBitmapUseAlpha, outputBitmap);

}

Executing that last line of code in the function causes an access violation error.

Right before this GrabAsyncFrame() function is called, I create the parameters it needs like this:

        ULONG frameId = 0;
        IWICImagingFactory* pWicFactory = NULL;
        IWICBitmap** outputBitmap = new IWICBitmap*;
        bool* pAbort = NULL;

        theCamera.GrabAsyncFrame(frameId, pWicFactory, outputBitmap, pAbort);

I'm kind of suspect to setting pWicFactory to NULL, and then using it soon after. But I couldn't figure out any other way to initialize the IWICImagingFactory objects.

So my question is: New question is posted below.

EDIT: If I try using new to initialize pWicFactory, I get a message saying

Error: object of abstract class type "IWICImagingFactory" is not allowed.

EDIT2:

After confirming that setting pWicFactory to NULL was the problem, I now need to know how to properly initialize an IWICImagingFactory object pointer. This is what I'm working with now:

            ULONG frameId = 0;
            IWICImagingFactory* pWicFactory = NULL;
/*new code*/CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pWicFactory));
            IWICBitmap** outputBitmap = new IWICBitmap*;
            bool* pAbort = NULL;
            theCamera.GrabAsyncFrame(frameId, pWicFactory, outputBitmap, pAbort);

Question: How do I properly initialize an IWICImagingFactory object pointer?

xcdemon05
  • 1,372
  • 5
  • 25
  • 49
  • So the CoCreateInstance call is failing? Assign the return value to an HRESULT variable and look at its description in the debugger, then edit the question with that description. – user1610015 Mar 15 '13 at 14:05
  • Aha. I just needed to call `CoInitialize(NULL)` before using `CoCreateInstance()`. Works fine now :) – xcdemon05 Mar 15 '13 at 14:30

2 Answers2

1

This declaration

IWICImagingFactory* pWicFactory = NULL;

is the culprit.

You're passing a NULL pointer to the function, which you then try to use, causing the error.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Okay as I stated in my question I had a feeling that was the problem, but to answer my question, what would be a better way of initializing it? Using `new` is the only other method I can think of, but I can't do that. – xcdemon05 Mar 15 '13 at 13:14
  • Try - CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pIWICFactory)); – Roger Rowland Mar 15 '13 at 13:16
  • @xcdemon05 So your question isn't really about the error you have, but how to create this object? – Some programmer dude Mar 15 '13 at 13:18
  • @JoachimPileborg My question was why isn't this working. I had a feeling initializing to NULL was part of the problem, but I wasn't sure. Knowing this now, my followup question is how to create the object. – xcdemon05 Mar 15 '13 at 13:21
  • @roger_rowland After that line of code, my debugger still says that the value of pWicFactory is 0x0000000000000000 – xcdemon05 Mar 15 '13 at 13:24
  • If you are on Windows 7 or 8 - try 'CLSID_WICImagingFactory1' instead of 'CLSID_WICImagingFactory'. – Roger Rowland Mar 15 '13 at 13:25
  • @roger_rowland It's not recognized by the compiler :( – xcdemon05 Mar 15 '13 at 13:27
  • What OS are you on? WIC needs minimum XP with SP2. – Roger Rowland Mar 15 '13 at 13:29
  • 1
    Ok, I suggest that you edit your original question to show the latest code and then we can see what you're doing now. – Roger Rowland Mar 15 '13 at 13:30
  • Before you can use `CoCreateInstance()` you need to call `CoInitialize(NULL)` (or the later `CoInitializeEx` version). Then before you exit the program, call `CoUninitialize()`. Beware that if you use `ComPtr` to hold your `IWICImagingFactory` pointer, you need to `Reset()` before calling CoUninitialize. – d7samurai Apr 20 '14 at 15:18
0

Aside from the nullpointer issue, you probably forgot to call CoInitialize first:

IWICImagingFactory* Factory;

...

CoInitializeEx(NULL, COINIT_MULTITHREADED); // do this during program init / before CoCreateInstance

CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&Factory));

// use factory..

CoUninitialize(); // do this before program exit.

Note that if you keep your factory pointer in a ComPtr (which I recommend), you need to release the factory interface before uninitializing. In that case you should do:

ComPtr<IWICImagingFactory> Factory;

...

CoInitializeEx(NULL, COINIT_MULTITHREADED); // do this during program init / before CoCreateInstance

CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&Factory));

// use factory..

Factory.Reset(); // do this before CoUninitialize

CoUninitialize(); // do this before program exit.

Also be sure to check the HRESULT returned by CoInitialize and CoCreateInstance (omitted here for brevity)...

EDIT: I now see in a comment that this was indeed your problem. I'll leave my answer though, in case others are as sloppy-sighted as me..

d7samurai
  • 3,086
  • 2
  • 30
  • 43