Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

How to prepare results of imgGrab() for AVI output in C++?

I hope this is an appropriate forum for this. I'm using VC++ 6.0 My image data is stored in a buffer that is populated via imgGrab(). I then go on to copy the buffer contents to a Direct Draw surface. This all works just fine.

I am also opening an AVI file, and attempting to write this image as a frame to the file. So far I am able to open the AVI, write the correct number of frames to it at the correct dimension, and close the AVI file without failure. The problem is that all of the buffer data is being written into the top 25% of vertical space only, the remaining 75% of vertical space in my AVI frames are black.

I'm attempting to add it as follows:

(note, all hard-coded numeric values below are actually calculated, I've shown actual values for clarity)

int iSize = 4000000; // (it's a 1000x1000 pixel 32bit image)

CBitmap* pBitmap;
pBitmap = new CBitmap();
pBitmap->CreateBitmap(1000, 1000, 1,32, pBuffer);

HBITMAP hbm = (HBITMAP)pBitmap->operator HBITMAP();

HDIB pDIB = BitmapToDIB(hbm, NULL);

if (pDIB==NULL)
return VIDEO_DIBCONVERSION;

if (ADD_FRAME_FROM_DIB_TO_AVI(pDIB, "DIB", 9) == FALSE)


this attempts to add a frame based on the device independant bitmap I've created.

The ADD_FRAME... method looks like this:

bool ADD_FRAME_FROM_DIB_TO_AVI(HANDLE dib, CString _compressor, int _frameRate)
{
LPBITMAPINFOHEADER lpbi;
if(count == 0)
{
lpbi = (LPBITMAPINFOHEADER)GlobalLock(dib);

if(! AVI_CreateStream(pfile, &ps, _frameRate,
(unsigned long) lpbi->biSizeImage,
(int) lpbi->biWidth,
(int) lpbi->biHeight))

{

//printf("Error - AVI_CreateStream()\n");
GlobalUnlock(lpbi);
return false;
}

if(! AVI_SetOptions(&ps, &psCompressed, lpbi, _compressor))
{
//printf("Error - AVI_SetOptions()\n");
GlobalUnlock(lpbi);
return false;
}

GlobalUnlock(lpbi);
}

lpbi = (LPBITMAPINFOHEADER)GlobalLock(dib);
if (lpbi)
{
if(! AVI_AddFrame(psCompressed, count * 1, lpbi))
{
//printf("Error - AVI_AddFrame()\n");
GlobalUnlock(lpbi);
return false;
}

GlobalUnlock(lpbi);
count++;
return true;
}
return false;
}

------------

I've tried doing everythign the same, but rather than actually creating the bitmap with the buffer data:
pBitmap->CreateBitmap(1000, 1000, 1,32, pBuffer);

I've created a CBitmap instance and loaded into it a "known good bitmap" that's actually an export from my current app.
When I do that, I get an AVI that is X number of frames of my known good bitmap. So I'm pretty certain all the AVI setup/writing functionality is working properly, it seems something is lost in the buffer, or I'm not translating the buffer that imgGrab() is producing correctly.

Does anybody have any suggestions?

thanks!
0 Kudos
Message 1 of 5
(5,321 Views)
Hello,

I would suggest taking a look at an example that has similar functionality. I have pasted a link below to an example that I found in the developer exchange that might help. This uses a C buffer to access the individual pixels. Hope this helps. Have a good day.

http://sine.ni.com/apps/we/niepd_web_display.display_epd4?p_guid=BC8B17EF6FF3514CE034080020E74861&p_node=DZ52490&p_source=external

-DC-
0 Kudos
Message 2 of 5
(5,321 Views)
Thanks! Yeah, I got it working already using something similar. Basically I wasn't offsetting RGB/Transparency values. I had do something like this: (for 32bit)

for( xx = 0, yy = 0; xx < m_iSize; xx++, yy += m_iByteStep)
{
pMappedBuffer[yy] = pBuffer[xx]; // blue
pMappedBuffer[yy+1] = pBuffer[xx]; // green
pMappedBuffer[yy+2] = pBuffer[xx]; // red
pBuffer[yy+3] = ( (BYTE*) a_pDDSD->lpSurface)[xx]; // transparency bit
}
0 Kudos
Message 3 of 5
(5,320 Views)

Hi,

Anyone know where the example referred to above exists now?

I tried to get it but the link is broken.

Thanks

Paul

0 Kudos
Message 4 of 5
(5,029 Views)
Paul,

The example is no longer available because of its age and the fact that a new AVI API has since then been released.  The API is available for VB, and will have to be called using ActiveX for it to be used in C++.  The container for the AVI session is called CWIMAQAVISession, and the various functions can be found in the NI Vision for Visual Basic Reference Help in the Start menu under Programs >> National Instruments >> Vision >> Documentation.

Regards,

Mike T
National Instruments
0 Kudos
Message 5 of 5
(4,997 Views)