Solved

Cannot create IWICBitmap from ID2D1Bitmap

Posted on 2013-01-10
5
2,972 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
  • 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 225 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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Magic Software info 18 105
Device same like our heart 12 49
I need an assist with a programming logic math question. 5 33
Java Loop 6 25
This article will show, step by step, how to integrate R code into a R Sweave document
This is about my first experience with programming Arduino.
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

743 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now