This example demonstrates how to create a filter module, containing frame filter implementations.
This article shows you how to:
You can find a Visual Studio project with a working filter module in the Samples\VC\DemoFilters directory of the IC Imaging Control installation.
In this article, the filter that was created in Writing a Frame Filter: Binarization will be used. For information on how a frame filter is implemented, please take a look at this article.
We will now extend the binarization filter from Writing a Frame Filter: Binarization to work inside a filter module.
A generic application that loads a filter does now know the filter's interface (like the CBinarizationFilter::enable or CBinarizationFilter::setThreshold methods). To be able to set filter parameters from that program, there is a generic filter interface implemented in IFrameFilter and FrameFilterImpl. The application can use IFrameFilter::getAvailableParameters to find out which parameters a filter supports and then call IFrameFilter::setParameter to alter parameter values.
To make the binarization filter support such parameters, it has to use FrameFilterImpl::addBoolParam or one of the other parameter registration methods. Extend the constructor of CBinarizationFilter to register two parameters:
CBinarizationFilter::CBinarizationFilter() : m_bEnabled( false ), m_threshold( 127 ) { // Add 'enable' parameter to enable or disable the binarization addBoolParam( "enable", &CBinarizationFilter::getEnable, &CBinarizationFilter::setEnable ); // Add 'threshold' parameter to set the binarization threshold addLongParam( "threshold", &CBinarizationFilter::getThreshold, &CBinarizationFilter::setThreshold ); }
The first parameter of the registration functions is the name by which an application can access the parameter. The second and third parameter are names of member functions of CBinarizationFilter. Replace the old enable and setThreshold methods by the following code:
public: // Enables or disables binarizarion DShowLib::tFilterError getEnable( bool& bEnable ); DShowLib::tFilterError setEnable( bool bEnable ); // Sets the threshold for the binarization DShowLib::tFilterError getThreshold( long& threshold ); DShowLib::tFilterError setThreshold( long threshold ); private: bool m_bEnabled; int m_threshold; };
These methods will be called when a program that loaded the filter calls setParameter( "enable", true ) or setParameter( "threshold", 100 ).
Their implementation is very simple:
/* * Returns the 'enabled' state of the binarization */ tFilterError CBinarizationFilter::getEnable( bool& bEnable ) { bEnable = m_bEnabled; return eNO_ERROR; } /* * Sets the 'enabled' state of the binarization */ tFilterError CBinarizationFilter::setEnable( bool bEnable ) { m_bEnabled = bEnable; return eNO_ERROR; } /* * Returns the binarization threshold */ tFilterError CBinarizationFilter::getThreshold( long& threshold ) { threshold = m_threshold; return eNO_ERROR; } /* * Sets the binarization threshold */ tFilterError CBinarizationFilter::setThreshold( long threshold ) { m_threshold = threshold; return eNO_ERROR; }
We now created a filter that should work with generic applications. Change the getStaticFilterInfo method to flag the filter as eFC_GENERIC:
FilterInfo CBinarizationFilter::getStaticFilterInfo() { // Return a filter name and declare the filter as eFC_GENERIC. FilterInfo fi = { L"Demo_Binarization", L"", eFC_GENERIC }; return fi; }
Go to the main file of your filter module and add a FILTERDLL_REGISTER_FILTER-line for the name of your filter class inside the FILTERDLL_BEGIN_EXPORT- FILTERDLL_END_EXPORT-section.
FILTERDLL_BEGIN_EXPORT() FILTERDLL_REGISTER_FILTER(CRotateTransform) FILTERDLL_REGISTER_FILTER(CDeNoiseTransform) FILTERDLL_REGISTER_FILTER(CSnapFilter) FILTERDLL_REGISTER_FILTER(CBinarizationFilter) FILTERDLL_END_EXPORT()
To add a user interface to your filter, you can override the IFrameFilter::hasDialog and IFrameFilter::callDialog methods.
The default implementation of hasDialog returns false, so we need to change it to true:
bool CBinarizationFilter::hasDialog() const { return true; }
In the callDialog implementation, we save the current settings of the filter, using IFrameFilter::getSettings and display a dialog box allowing the user to change the filter's parameters. If the user exists the dialog by clicking the cancel button, the filter setting are restored to the saved values.
bool CBinarizationFilter::callDialog( HWND hParent ) { // Save settings std::string data = getSettings(); // Display modal dialog. // Pass the pointer to this instance to WM_INITDIALOG. INT_PTR result = DialogBoxParam( g_hInst, MAKEINTRESOURCE(IDD_BINARIZATION_CONFIG), hParent, BinarizationConfigDlgProc, (LPARAM)this ); // When the user clicked 'cancel' restore settings if( result == IDCANCEL ) { setSettings( data ); } // Return true when the dialog was displayed. return result >= 1; }