?
Solved

Cannot create IWICBitmap from ID2D1Bitmap

Posted on 2013-01-10
5
Medium Priority
?
3,237 Views
Last Modified: 2013-01-11
I am reading pixel data from a buffer which is loaded by a camera.  I am able to successfully create an ID2D1Bitmap from this pixel data.  However, I cannot seem to create an IWICBitmap from the ID2D1Bitmap.  Here is the code I am using.  This function "ImgFromPixelArray" is called when a camera frame has been loaded into the pixel buffer.  The pass parameters are:

W = Width of image
H = Height of image
Stride = Stride of image
PF = pixelformat
PixelArray = address of pixel buffer

Elsewhere in the app, I (successfully) create a D2D1Factory (called mpD2DFact) which in turn creates the HwndRenderTarget used below, called mpRTarg.  I also create IWICImagingFactory elsewhere in the class called mpWICFactory, which is also used below.

BOOL CViewerPlus::ImgFromPixelArray(DWORD W, DWORD H, int Stride, UINT PF, char* PixelArray)
{
    BYTE* Addr = (BYTE*)PixelArray;

    //Create a D2D1_SIZE_U struct using the size of the bitmap.
    D2D1_SIZE_U Size = D2D1::SizeU(W, H);

    //Release the pointer to the ID2D1Bitmap and NULL it out if it has already been defined.
    if (mpImgD2D != NULL)
      mpImgD2D->Release();
    mpImgD2D = NULL;

     //Use the render target to create the ID2D1Bitmap called mpImgD2D.
    HRESULT hr = mpRTarg->CreateBitmap(Size, (void*)PixelArray, Stride, mBmpProp, &mpImgD2D);
    //The above returns hr = S_OK

    //Now create a temporary IWICBitmap object.  At the moment, this temporary bitmap  
    //will be empty, but is created in the right size and format for us to use.
    IWICBitmap *WICBmp;
    D2D1_SIZE_U ImgSize = mpImgD2D->GetPixelSize();
    hr = mpWICFactory->CreateBitmap(ImgSize.width, ImgSize.height, GUID_WICPixelFormat32bppBGR, WICBitmapCacheOnLoad, &WICBmp);
    //The above returns hr = S_OK

    //Now we create a Direct2D render target based on our temporary WIC bitmap.
    ID2D1RenderTarget *WICRTarg;
    hr = mpD2DFact->CreateWicBitmapRenderTarget(WICBmp, D2D1::RenderTargetProperties(), &WICRTarg);
    //The above returns hr = S_OK

    //Now draw D2D1Bitmap image using the WIC render target, this should write the image
    //into the WICBitmap;
    WICRTarg->BeginDraw();
    WICRTarg->DrawBitmap(mpImgD2D);
    hr = WICRTarg->EndDraw();
    //The above returns hr = 0x88990015

    return 0;
}

Open in new window


The very last step is the one that fails, and I believe that the returned error 0x88990015 indicates "The resource was realized on the wrong render target."  

If I change the code around so that the ID2D1Bitmap (mpImgD2D) is created by the WICRenderTarget (WICRTarg) rather than the HwndRenderTarget (mpRTarg), then the code works - I can draw the ID2D1Bitmap (mpImgD2D) on the IWICBitmap (WICBmp).  However, doing so prevents me from drawing mpImgD2D on the screen elsewhere in the app using the HwndRenderTarget.

So the problem is fundamentally this:  If you create an ID2D1Bitmap with a HwndRenderTarget, you can't draw that Bitmap on an IWICBitmap using a different render target (in this case, the WICBitmapRenderTarget).  And conversely, if you create an ID2D1Bitmap with a WICBitmapRenderTarget, then you can't draw it on the screen using a HwndRenderTarget.  SO, if you have an image, and need to go back and forth between an ID2D1Bitmap format (for screen display) and an IWICBitmap format (for reading and writing to disk), how do you do it?

Thank you very much.
0
Comment
Question by:debrunson
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 16

Expert Comment

by:George Tokas
ID: 38766335
The obvious workaround would have been to create a pair of d2d images one to work with display and one to work for other purposes...
So have the main image for the most important task and create a secondary clone of it when needed for other secondary tasks.

George Tokas.
P.S. Not yet that deep to d2d that's and why I can't be more specific.
0
 

Author Comment

by:debrunson
ID: 38767834
So far that's all I can come up with as well.  

Surely there is a way to do the following:
a.  Read a WICBitmap from a file (I can do this)
b.  Convert that WICBitmap to a D2D1Bitmap (I can do this)
c.  Display (and manipulate) the D2D1Bitmap (I can do this too)
d.  Convert the manipulated D2D1Bitmap back into a WICBitmap for storage (I can't do this)

Am I missing something?  Or, perhaps you are supposed to load, manipulate, and store the WICBitmap, converting to D2D1Bitmap only for display?
0
 
LVL 16

Accepted Solution

by:
George Tokas earned 900 total points
ID: 38768156
Loooooong time ago when I was a kid I climbed a tree and couldn't come down...
When I asked my late father to help me he said to me "do what you have done climbing but in reverse order...".
A few mins later I was down...
Said the same to my son a decade ago and the result was - again - the same, success!

Even though this is a story from an old man applies all the time.
For sure you are missing something... There is no way to do something one way and can not reverse the order...
But depending on the needs of your application I think that:
>>converting to D2D1Bitmap only for display?
would be the fastest and most probably the BEST idea...
If you decide to use this approach - which I agree totally - assign yourself the answer.

George Tokas.
0
 

Author Comment

by:debrunson
ID: 38768774
I think you must be correct.  Unforunately with my limited IQ, I do not immediately see how to reverse the process of converting a WICBitmap to a D2D1Bitmap.  It currently appears to be a one-way trip, like jumping out of an airplane with a parachute.  However I also think that the best thing to do is to keep everything in WICBitmap form until time to throw it on the screen.  I will give you the points but reserve the right to ask more questions!
0
 
LVL 16

Expert Comment

by:George Tokas
ID: 38768926
What I didn't mention in the story I shared is that I was under constant supervision of my late father when I was climb down the tree and the same was my son from me...
Now for the right to ask more questions, that is why we are all here...
The reason I mentioned that the best way is the one you describe is because all operations are in memory and those are faster since there is no delay for displaying reasons.
Now if the conversion from the memory side (WICBitmap) to the display side is fast enough then there will be no performance issues...
Another thing now:
At this time I am dealing with LAN capture-transmit-receive-displaying solution based on mpeg encoding/decoding...
As you can see I am dealing with almost the same thing and there is allways the reverse order even though it was hell to work with with visual c++ when the code library was made with mingw...
If I can help just send me a mail if I don't see your question(s).

George Tokas.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…
Starting up a Project
Suggested Courses

801 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question