|
I suggest checking out DIBAPI.H, DIBUTIL.C and DIBUTIL.H from microsoft samples. These will allow you to convert to/from HBITMAP/DIB.
Rod
|
|
|
|
|
|
Hmm.. Still having problems. If it's outside scope of this forum/thread, please say so.
So I have my pointer to the bitmap data: a_pBuffer.
I first create a CBitmap:
CBitmap* pBitmap;
pBitmap = new CBitmap();
if (pBitmap->CreateBitmap(1000,1000,1,32, a_pBuffer) )
return VIDEO_CREATEBITMAP;
and then I need a DIB to send to your function, so I try:
HBITMAP hbm = (HBITMAP) pBitmap->operator HBITMAP ();
HDIB pDIB = BitmapToDIB(hbm, NULL);
ADD_FRAME_FROM_DIB_TO_AVI(pDIB, "DIB", 10);
--------
The problem is that I can't seem to get a good handle. I create the bitmap just fine, but then this line: HBITMAP hbm = (HBITMAP) pBitmap->operator HBITMAP (); executes and hbm is equal to 0x00000000 and consequently when I call the function BitmapToDIB from dibapi.h, the value is still 0x00000000.
Is there something blatant I'm doing wrong?
thanks again
-Paul
|
|
|
|
|
CBitmap has a few quirks. For a sanity check try CBitmap::LoadBitmap( LPCTSTR lpszResourceName ) and see if your handle is valid.
Here is something ugly I had to do once. Notice how you must initialize CBitmap!
int w = 40;
int h = 80;
RECT rectC;
wnd->GetClientRect(&rectC);
CDC* wDc = wnd->GetDC();
CDC bitmapDc;
bitmapDc.CreateCompatibleDC(wDc);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(wDc, w, h);
CBitmap* oldBitmap = (CBitmap*) bitmapDc.SelectObject(&bitmap);
bitmapDc.StretchBlt(0, 0, w, h, wDc, 20, 315, w, h, SRCCOPY);
CxImage* img = new CxImage();
img->CreateFromHBITMAP((HBITMAP) bitmap);
//img->CreateFromHANDLE(hdib); // no
img->SetJpegQuality(255);
img->Save("foo.jpg", CXIMAGE_FORMAT_JPG);
delete img;
Rod
|
|
|
|
|
hmm.. still having problems. I've been able to setup the bitmap and handles correctly (I think) -but I'm concerned thus far with two things.
I create a bitmap:
CBitmap* pBitmap;
pBitmap = new CBitmap();
dwReturn = pBitmap->CreateBitmap(1000,1000,1,32, NULL);
create the handle:
HBITMAP hbm = pBitmap->operator HBITMAP ();
HDIB pDIB = BitmapToDIB(hbm, NULL);
set the bits:
dwReturn = pBitmap->SetBitmapBits(1000*1000, pBuffer);
(pBuffer is a pointer to the array of bitmap values, on my all white screen, each array value holds FFFFFFFF
and then I try to add it to the AVI:
if (ADD_FRAME_FROM_DIB_TO_AVI(pDIB, "DIB", 9) == FALSE)
The first thing I notice is that within your ADD_FRAME method:
lpbi = (LPBITMAPINFOHEADER)GlobalLock(dib);
if I watch lpbi, it shows a bit-depth of 24, not 32, and biSizeImage of 3000000, rather than 4000000 as I'd expect having set the CBitmap instance up with 32 and a size of (1000*1000*4)
The resulting AVI, while 1000x1000 pixels, only has graphics in the top 1/4 of the screen (fully across horizontally, only filling vertically 1/4 of the way down)
Any ideas why this might be?
thanks
-Paul
|
|
|
|
|
I have been attempting to use aviUtil to write frames from a CxImage to a specific frame of an avi. I have a CxImage called out_image, and an output stream called out_stream. my original attempt looked like this:
for(curr_frame=first_frame;curr_frame<last_frame;curr_frame++){<br />
out_image.Save("out.jpg",CXIMAGE_FORMAT_JPG);<br />
Results=AVIStreamWrite(out_stream,curr_frame,1,(LPBYTE)out_image.GetBits(),out_bmpHdr.biSizeImage,AVIIF_KEYFRAME,NULL,NULL);<br />
}
Unfortunately, the output video contained only black frames, not my original image. The image is correct, as out_image.Save(....) produces the correct frame. Then I found aviUtil. The problem I am having is that I believe I need to do this:
for(curr_frame=first_frame;curr_frame<last_frame;curr_frame++){<br />
out_image.Save("out.jpg",CXIMAGE_FORMAT_JPG);<br />
AVI_AddFrame(out_stream, curr_frame, lpbi);<br />
}
My question is how do I get the the data bits lpbi from out_image? Or is there a simple adjustment to the one line:
Results=AVIStreamWrite(out_stream,curr_frame,1,(LPBYTE)out_image.GetBits(),out_bmpHdr.biSizeImage,AVIIF_KEYFRAME,NULL,NULL);
that will make this work?
|
|
|
|
|
I don't use this class but I use CxImage , what I did was derive a class from CxImage and used the following:-
BITMAPINFOHEADER *GetBITMAPINFOHEADER() { return(&head); }<br />
<br />
<br />
BITMAPINFO* CBMPFileCxImage::GetInfo(void)<br />
{<br />
static BITMAPINFO bmInfo;<br />
<br />
if(!m_Image.IsValid())<br />
return((BITMAPINFO*) NULL);<br />
<br />
CopyMemory(&bmInfo.bmiHeader, GetInfoHeader(), sizeof(BITMAPINFO));<br />
<br />
return(&bmInfo);<br />
}<br />
<br />
BITMAPINFOHEADER* CBMPFileCxImage::GetInfoHeader()<br />
{<br />
if(m_Image.IsValid())<br />
return(m_Image.GetBITMAPINFOHEADER());<br />
else<br />
return((BITMAPINFOHEADER*) NULL);<br />
}<br />
Thta is "my" method, there may be other (better) ways, hope it helps
"Committee--a group of men who individually can do nothing but as a group decide that nothing can be done." - Fred Allen
|
|
|
|
|
I appreciate your help. I have attempted to modify the class CxImage to include your new functions, however, I am having a problem with the declaration of several of your variables. I have added the functions directly to ximage.h and ximage.cpp as follows:
BITMAPINFOHEADER *GetBITMAPINFOHEADER() <br />
{ <br />
return(&head); <br />
}<br />
<br />
BITMAPINFO* CxImage::GetInfo(void)<br />
{<br />
static BITMAPINFO bmInfo;<br />
<br />
if(!m_Image.IsValid())<br />
{<br />
return((BITMAPINFO*) NULL);<br />
}<br />
<br />
CopyMemory(&bmInfo.bmiHeader, GetInfoHeader(), sizeof(BITMAPINFO));<br />
<br />
return(&bmInfo);<br />
}<br />
<br />
BITMAPINFOHEADER* CxImage::GetInfoHeader()<br />
{<br />
if(m_Image.IsValid())<br />
return(m_Image.GetBITMAPINFOHEADER());<br />
else<br />
return((BITMAPINFOHEADER*) NULL);<br />
}
however, m_Image and head both appear as indeclared identifiers. Where and how should I declare them. (sorry if I am asking a very simplistic question... I have taught myself enough C++ to get to this point because I need a piece of software to do just what I need, so I'm really a beginner with no experience as of yet)
|
|
|
|
|
I tried to send you email but it got returned! You don't need to modify CxImage
// get DDB bitmap
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER) GlobalLock((new CxImage(path + fileName, CXIMAGE_FORMAT_PNG))->GetDIB());
if(lpbi != NULL)
{
.
.
.
GlobalUnlock(lpbi);
}
or just call
CxImage img(path + fileName, CXIMAGE_FORMAT_PNG); // for a .png
ADD_FRAME_FROM_DIB_TO_AVI(&img.GetDIB(), "CVID" /* or DIB */, 25); // for example (aviUtil.h)
|
|
|
|
|
Using these methods I still have a problem each way:
using
ADD_FRAME_FROM_DIB_TO_AVI(&img.GetDIB(),"CVID",25);
I get an error:
c:\oldultc64\tests\testsdlg.cpp(338) : error C2102: '&' requires l-value
using this code:
LPBITMAPINFOHEADER lpbiout = (LPBITMAPINFOHEADER) GlobalLock<code>(out_image.GetDIB());<br />
if(lpbiout != NULL)<br />
{<br />
GlobalUnlock(lpbi);<br />
}<br />
Results=AVIStreamWrite(out_stream,cframe,1,lpbiout,lpbiout->biSizeImage,AVIIF_KEYFRAME,NULL,NULL);
everything seems to run properly, but if a windows explorer window with the output avi is open, I get a windows explorer error which shuts it down. The file is unplayable. Where have I gone wrong on this?
|
|
|
|
|
Maybe this is the easiest way of asking the question... this is my code:
void CTestsDlg::ReadFrames()<br />
<br />
{<br />
Results=AVIFileOpen(&out_file,out_name,OF_WRITE|OF_CREATE,NULL);<br />
if(Results!=0){Results=MessageBox("Failure creating ouput avi","AVIFileOpen Error", MB_OK);}<br />
out_bmpHdr=in_bmpHdr;<br />
out_stream_info=in_stream_info;<br />
out_stream_info.fccHandler = mmioFOURCC('C','V','I','D');
Results=AVIFileCreateStream(out_file,&out_stream,&out_stream_info);<br />
if(Results!=0){Results=MessageBox(<br />
"Error Creating Stream!","AVIFileCreateStream Error",MB_OK);<br />
AVIFileRelease(out_file);}<br />
Results=AVIStreamSetFormat(out_stream,0,&out_bmpHdr,sizeof(out_bmpHdr));<br />
if(Results!=0){<br />
Results=MessageBox("Error Setting output stream format","AVIStreamSetFormat Error",MB_OK);<br />
AVIStreamRelease(out_stream);<br />
AVIFileRelease(out_file);<br />
return;}<br />
<br />
for(cframe=curr_frame;cframe<num_frames;cframe++){<br />
get_frame=AVIStreamGetFrameOpen(in_stream,NULL);<br />
lpbi=(LPSTR)AVIStreamGetFrame(get_frame,cframe);<br />
in_bmp=CreateBitmap((BYTE*)AVI_FindDIBBits(lpbi),(LPBITMAPINFOHEADER)lpbi);<br />
in_image.CreateFromHBITMAP(in_bmp);
<br />
<br />
out_image=in_image;<br />
out_image.Save("out1.jpg",CXIMAGE_FORMAT_JPG);<br />
Results=AVIStreamWrite(out_stream,cframe,1,out_image.GetBits(),out_image.GetSize(),AVIIF_KEYFRAME,NULL,NULL);<br />
}<br />
<br />
AVIStreamRelease(out_stream);<br />
AVIFileRelease(out_file);<br />
<br />
}
It produces a valid avi, but the frames are pure black. Any idea where I went wrong?
|
|
|
|
|
I like programming to control camera, multimedia and system application .
I want help !!!
I3.DVR International Inc.
Best Regards
Tran Tien Dung, Binh Dinh, Vietnam
|
|
|
|
|
I did not go over the source code yet. Does this include support for audio and synchronization of audio?
|
|
|
|
|