PDA

View Full Version : URGENT: help on Rotation (Fip)



Bolle
December 29, 2006, 23:27:38
Finaly I got the right Lib Files for debugging und developing is getting much faster :p

...but there are still some questions...

I have the rotation flip filter from the standard-ftf. In live mode the image ist show correct (means flipped), but when I save the snaped images from the buffer to disk they aren't! How can I save the Images flipped also?

First I get the Filter...


// Load the standard frame filter.
#ifdef _DEBUG
_pRotFlipFilter = FilterLoader::createFilter( "Rotate Flip", // Filter name.
"stdfiltersd.ftf" ); // Module file.
#else
_pRotFlipFilter = FilterLoader::createFilter( "Rotate Flip", // Filter name.
"stdfilters.ftf" ); // Module file.
#endif

//_pRotFlipFilter = FilterLoader::createFilter( "Rotate Flip" );
if( _pRotFlipFilter != NULL)
{
_pRotFlipFilter->setParameter( "Flip V", true );
_pRotFlipFilter->setParameter( "Flip H", true );
if( !_grabber->setDeviceFrameFilters( _pRotFlipFilter.get()) )
{
std::cout << "Failed to add the the standard frame filters to the grabber!" << std::endl;
}
_pSink = FrameHandlerSink::create( _pRotFlipFilter.get(), eRGB24, 1 );
}


Then I allocate the Buffer...



_pSink->setSnapMode(true);
// Set the sink.
_grabber->setSinkType(_pSink);
if(!_grabber->prepareLive(true))
{
QMessageBox msgBoxInformation;
msgBoxInformation.setWindowTitle(tr("CCA Capture Warning"));
msgBoxInformation.setIcon(QMessageBox::Warning);
msgBoxInformation.setText("Could not render the VideoFormat into a eRGB24 sink.");
msgBoxInformation.setStandardButtons(QMessageBox:: Ok);
msgBoxInformation.exec();
return false;
}
FrameTypeInfo info;
_pSink->getOutputFrameType(info);

BYTE* pBuf[1];
for(int i=0; i<1; i++){
pBuf[i] = new BYTE[info.buffersize];
}
_ciMemBuffColl = MemBufferCollection::create(info, 1, pBuf );
if(_ciMemBuffColl == 0 || !_pSink->setMemBufferCollection(_ciMemBuffColl)){
QMessageBox msgBoxInformation;
msgBoxInformation.setWindowTitle(tr("CCA Capture Warning"));
msgBoxInformation.setIcon(QMessageBox::Warning);
msgBoxInformation.setText("Could not set the new MemBufferCollection,\nbecause types do not match.");
msgBoxInformation.setStandardButtons(QMessageBox:: Ok);
msgBoxInformation.exec();
return false;
}


...and finally I save the Image...



_pSink->snapImages(1);
//_grabber->suspendLive();
callError();
try{
_pSink->getMemBufferCollection()->save( filename );
}
catch(...)
{
callError();
}

Bolle
December 30, 2006, 03:40:29
ok, I did I myself :p



_pSink->snapImages(1);

HDC dc = CreateCompatibleDC( NULL );
int bpp = GetDeviceCaps(dc,BITSPIXEL);
DeleteDC(dc);

// Retrieve the bitmap info header of the image buffer to
// get the width and height of the image buffer
smart_ptr<BITMAPINFOHEADER> pInf = _pSink->getMemBufferCollection()->getBuffer(0)->getBitmapInfoHeader();

// Allocate memory for the bitmap
DWORD Size = ((bpp>>3) * pInf->biWidth * pInf->biHeight);
BYTE *bytes = NULL;
bytes = new BYTE[Size];

// Create the bitmap
m_hCameraBitmap = CreateBitmap(pInf->biWidth,
pInf->biHeight,1,bpp,bytes);

// The memory is not longer needed, so we can delete it
delete [] bytes;

HDC memDC;
memDC = CreateCompatibleDC(NULL);

// Select the bitmap of the memory DC to draw in.
SelectObject(memDC, m_hCameraBitmap);

int nLines = StretchDIBits(
memDC, // Handle to the device
pInf->biWidth-1, // x-coord of destination upper-left corner
pInf->biHeight-1, // y-coord of destination upper-left corner
-pInf->biWidth, // width of destination rectangle
-pInf->biHeight, // height of destination rectangle
0, // x-coord of source upper-left corner
0, // y-coord of source upper-left corner
pInf->biWidth, // Source rectangle width
pInf->biHeight, // Source rectangle height
_pSink->getMemBufferCollection()->getBuffer(0)->getPtr(), // bitmap bits
reinterpret_cast<LPBITMAPINFO>( &*pInf ), // bitmap data
DIB_RGB_COLORS, // usage options
SRCCOPY // raster operation code
);

DeleteDC( memDC);

Stefan Geissler
January 2, 2007, 15:30:55
Hello Bolle,

I just rebuild your sample. First off all you should only pass the the frame filter's name and not the module file to DShowLib::FilterLoader::createFilter().

The initialization of the grabber is done in the ::OnInitDialog() method of the dialog application. The dialog's window contains a CStatic field whose ID is IDC_STATICVIDEOWINDOW. The live video should be displayed in this CStatic and in the size of the CStatic:

RECT r;
::GetClientRect(GetDlgItem(IDC_STATICVIDEOWINDOW)->m_hWnd, &r );

m_cGrabber.setHWND(GetDlgItem(IDC_STATICVIDEOWINDO W)->m_hWnd );
m_cGrabber.setDefaultWindowPosition(false);
m_cGrabber.setWindowSize( r.right, r.bottom );

In the next step the "Rotate Flip" is to be loaded and its parameters should be set:

_pRotFlipFilter = DShowLib::FilterLoader::createFilter("Rotate Flip");
// Check wether the filter could be loaded successfully.
if( _pRotFlipFilter == NULL)
{
MessageBox("Failed to load the \"Rotate Flip\" frame filter!","Error",MB_OK|MB_ICONEXCLAMATION);
}
else
{
// The frame filter has been loaded successfully. Now it should be added
// to the Grabber object.
if( !m_cGrabber.setDeviceFrameFilters( _pRotFlipFilter.get()) )
{
MessageBox("Failed to add the \"Rotate Flip\" frame filter to the grabber!","Error",MB_OK|MB_ICONEXCLAMATION);
}
else
{
_pRotFlipFilter->setParameter( "Flip V", true );
_pRotFlipFilter->setParameter( "Flip H", true );
}
}


At lease the sink for saving the images is to be created. Only three lines of code are necessary for this task:

m_pSink = DShowLib::FrameHandlerSink::create( DShowLib::eRGB24, 5 );
m_pSink->setSnapMode( true );
m_cGrabber.setSinkType( m_pSink );


The device is selected using IC Imaging Control's device page:

m_cGrabber.showDevicePage();
if( m_cGrabber.isDevValid())
{
m_cGrabber.startLive();
}



Saving an image is done in a button event handler. Test like is video running etc are not implemented to keep the sample short:

void CRotateFlip_vc6Dlg::OnButtonsnap()
{
m_pSink->snapImages( 1, 2000 );
m_pSink->getLastAcqMemBuffer()->save("Test.bmp" );
}


I tested this and found the image saved bottom up as expected. It was rotated by the "Rotate Flip" filter.