Using Windows Image Acquisition (WIA) from C++/CLI Managed Code

G

Guest

I am using Visual Studio 2005 and wish to program using managed C++ code.

I am writing an application to take still images from a webcam.

I have created an interop 'reference' to the platform SDK dll for Windows
Image Acquisition (WIA). This has created a set of classes under
"Interop.WIALib.1.0.dll"
Here is the bewildering set of classes it creates:

WIALib::CollectionClass
WIALib::DeviceInfoClass
WIALib::ItemClass
WIALib::SafeWiaClass
WIALib::WiaClass
WIALib::Collection
WIALib::DeviceInfo
WIALib::ICollection
WIALib::Item
WIALib::IWia
WIALib::IWiaDeviceInfo
WIALib::IWiaDispatchItem
WIALib::SafeWia
WIALib::Wia
WIALib::WiaProtocol
WIALib::WiaDeviceInfoPropertyId
WIALib::WiaFlag
WIALib::WiaIntent
WIALib::WiaItemPropertyId

Unfortunately I have no idea how to use these generated classes because
there appears to be no documentation other than for the original COM class
library and and that documentation only relates to unmanaged code that makes
use of pointers and interfaces.

My semi-random stab at getting it to take a picture is as follows.
Needless to say, this code does not work, so your help in correcting the
code or explaining how the classes work would be most appreciated.

using namespace WIALib;
WiaClass^ myWia = gcnew WiaClass();

int iCnt = myWia->Devices->Count;
Collection^ myDeviceInfo = myWia->Devices;
Collections::IEnumerator^ myEnumerator = myDeviceInfo->GetEnumerator();

myEnumerator->MoveNext();
IWiaDeviceInfo^ myDev = (IWiaDeviceInfo^)myEnumerator->Current;
Item^ myItem = myDev->Create();
if (myItem->ConnectStatus=="connected")
{
myItem->TakePicture();
myItem->Transfer("clipboard",false);
}

Regards,
Nicholas Lee
 
G

Guest

Update:
I have now produced the following code that uses the "GetItemsFromUI" method
of obtaining images.
This code presents the user with a dialog box from which to select an image,
and it then successfully grabs that image and saves it to disk.
However, what I actually need is to programmatically grab images without
user interaction and to save those images to memory raher than to disk so I
can do some image processing operations on them.
To achieve this I think I need my code to use the "TakePicture" and
"Transfer" methods, but I am unable to find the right syntax to make this
work. Any assistance would be greatly appreciated.

using namespace WIALib;
WiaClass^ hWia = gcnew WiaClass();

int i = 0;

Collection^ hDeviceCollection = hWia->Devices;

IEnumerator^ hDeviceEnumerator = hDeviceCollection->GetEnumerator();

while (hDeviceEnumerator->MoveNext())
{
DeviceInfo^ hDeviceInfo = (DeviceInfo^)hDeviceEnumerator->Current;

Item^ hItem = hDeviceInfo->Create();

Collection^ hImageCollection =
hItem->GetItemsFromUI(WiaFlag::SingleImage, WiaIntent::ImageTypeColor);

IEnumerator^ hItemEnumerator = hImageCollection->GetEnumerator();

while (hItemEnumerator->MoveNext())
{
Item^ hPictureItem = (Item^)hItemEnumerator->Current;
i++;
String^ hString = "C:\\MyPicture"+i+".bmp";
hPictureItem->Transfer(hString,false);
}
}
 
G

Guest

Update:
I have now solved my problem by using a differrent dll.
I have now obtained wiaaut.dll which I put in my system32 directory,
registered the dll, and then did 'add reference' from VS2005. This creates
"Interop.WIA.1.0.dll" which is a much easier to use type libarary.

To choose which camera to use, the followng code works...
using namespace WIA; // "Interop.WIA.1.0.dll" referenced from wiaaut.dll

// Select a camera device using a user interface
hLeftEyeCameraID = nullptr;
CommonDialogClass^ class1 = gcnew CommonDialogClass();
Device^ hDevice = nullptr;
ImageFile^ hImagefile = nullptr;

hDevice = class1->ShowSelectDevice(WiaDeviceType::UnspecifiedDeviceType,
true,false);
if (hDevice != nullptr)
{
hLeftEyeCameraID = hDevice->DeviceID;
// Display the ID for the selected camera
MessageBox::Show(hLeftEyeCameraID);
}


To then take a picture with the chosen camera, the following code works...

// Having identified a camera ID, connect to it.
DeviceManager^ manager = gcnew DeviceManagerClass();
hDevice = nullptr;
for each(DeviceInfo^ hDeviceInfo in manager->DeviceInfos)
{
if (hDeviceInfo->DeviceID == hLeftEyeCameraID)
{
hDevice = hDeviceInfo->Connect();
break;
}
}

if (hDevice != nullptr)
{
// We now have a connection to the left eye.
Item^ hItem = hDevice->ExecuteCommand(CommandID::wiaCommandTakePicture);
for each(String^ hFormat in hItem->Formats)
{
if (hFormat == FormatID::wiaFormatBMP)
{
hImagefile = (ImageFile^)hItem->Transfer(hFormat);
break;
}
}
}

if (hImagefile != nullptr)
{
String^ hString = "C:\\MyPic.bmp";
try
{
hImagefile->SaveFile(hString);
}
catch (System::Runtime::InteropServices::COMException^ e)
{
// An exception will be generated if the save fails, e.g. if the file
already exists.
MessageBox::Show(e->Message);
}
}


For my application I will not actually be saving the image, I will be doing
image processing with it instead. Luckily the hImagefile provides access to
the underlying 'FileData' so I will be using that.
 
G

Guest

This works, but for me it is too slow (4-5 sec per image). Is there any way
to make it almost realtime?
I need to capture images, make some image processing and then make something
like video stream from them...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top