Here at PixeLINK we write a lot of code that uses our API. Most of the time the code has to be generic so that it can be used with all of our cameras. Over time we found that we were doing a lot of the same things over and over, and therefore decided to create a library of the commonly done things so that we could write once, test, and reuse. We called the library PixeLINK+ because it's the PixeLINK API, *plus* a whole lot more.
For example, this code uses the PixeLINK API to capture an image to a file:
float params; U32 numParams; U32 flags; numParams = 4; PxLGetFeature(hCamera, FEATURE_ROI, &flags, &numParams, ¶ms); const U32 roiWidth = (U32)params[FEATURE_ROI_PARAM_WIDTH]; const U32 roiHeight = (U32)params[FEATURE_ROI_PARAM_HEIGHT]; numParams = 2; PxLGetFeature(hCamera, FEATURE_PIXEL_ADDRESSING, &flags, &numParams, ¶ms); const U32 pixelAddressingValue = (U32)params[FEATURE_PIXEL_ADDRESSING_PARAM_VALUE]; const U32 numPixels = (roiWidth / pixelAddressingValue) * (roiHeight / pixelAddressingValue); numParams = 1; PxLGetFeature(hCamera, FEATURE_PIXEL_FORMAT, &flags, &numParams, ¶ms); const U32 pixelFormat = (U32)params; const U32 pixelSize = GetPixelSize(pixelFormat); // Function implemented elsewhere const U32 frameSize = pixelSize * numPixels; U8* pFrameData = (U8*)malloc(frameSize); FRAME_DESC frameDesc; frameDesc.uSize = sizeof(frameDesc); PxLGetNextFrame(hCamera, frameSize, pFrameData, &frameDesc); U32 imageSize = 0; PxLFormatImage(pFrameData, &frameDesc, IMAGE_FORMAT_JPEG, NULL, &imageSize); U8* pImageData = (U8*)malloc(imageSize); PxLFormatImage(pFrameData, &frameDesc, IMAGE_FORMAT_JPEG, pImageData, &imageSize); FILE* pFile = fopen("capturedImage.jpg", "wb"); fwrite((void*)pImageData, sizeof(char), imageSize, pFile); fclose(pFile); free(pImageData); free(pFrameData);
This code can be reduced to this one PixeLINK+ function:
PxLCaptureImageToFile(hCamera, IMAGE_FORMAT_JPEG, "capturedImage.jpg");
PixeLINK+ also has functions like
PxLSetExposure PxLEnableAutoExposure PxLAutoWhiteBalanceOnce PxLSetToMaxRoi PxLEnableHardwareTriggering PxLEnableGpioModeNormal
We figured, if it makes our lives simpler, maybe it can simplify the lives of others using our API, i.e. you. So, we decided to release PixeLINK+, source code and binaries, with our SDK. PixeLINK+ is provided with the SDK as:
A static library;
A dynamic link library (DLL); and
Source code with a Visual Studio 2008 solution for building the static lib and DLL.
These can be found in the PixeLINK+ directory under the %ProgramFiles%\PixeLINK directory. The binaries are provided and may be used 'as is'. The source code is provided for your information or reference. Feel free to use some or all of the code as you need. If you do find an error in the code, or think it's lacking something, please let us know so that others may benefit. Any and all feedback is greatly appreciated.
The function prototypes in the PixeLINK+.h header file are grouped corresponding to the tabs in Capture OEM.
A lot of the code could be more easily implemented in C++, taking advantage of std::vector etc., but is written in C to provide functionality at the "lowest common denominator".
Note that some error handling is hidden. It is assumed that most 'gets' of information from the camera will succeed, assuming you've checked that the functionality is supported. (e.g. A call to get the brightness should not be called if brightness is not supported by the camera).
Note too that some of the functions -- e.g. PxLLetUserSelectACamera, PxLWaitForAnyKey, PxLThreadSafePrintf* -- are suitable only for use in a shell (cmd.exe) environment.
All the functions are written to be thread-safe, but that does not mean that two threads can interact with the same camera. Two threads can and may use PixeLINK+ to interact with two different cameras.