Frequently Asked Questions

Thomas Dideriksen

How do I create a NikonDevice object?

You don't create NikonDevice objects directly. Instead, you create a NikonManager object and hooks up to the DeviceAdded event. The event handler will receive the NikonDevice object that represents your physical DSLR camera.

manager.DeviceAdded += new DeviceAddedDelegate(onDeviceAdded);

...

void onDeviceAdded(NikonManager sender, NikonDevice device)
{
    // TODO: Store the 'device' object so it can be used later
}

Why isn't the DeviceAdded event fired when I attach my DSLR?

Try to create your DeviceManager object like this

// Note: Replace 'Type0003.md3' with the MD3 file that matches your DSLR
NikonManager manager = new NikonManager("Type0003.md3"); 

This will cause the library too look for the MD3 file in the 'current working directory' which is usually the directory where your application executable (.exe) is located.

Now, copy the MD3 file along with the accompanying NkdPTP.dll to this directory and try again.

(Are you using a D40, D60, D80 or D200? See below)

Why does it take so long for my camera to be recognized?

When you connect your camera to your PC, the Nikon SDK (apparently) have to enumerate all the items on your SD/CF card. If you have a large, slow card and a lot of photos this can take a very long time. The DeviceAdded event will NOT be fired until this internal enumeration process is complete.
The solution is to empty your memory card.
Alternatively, you can remove your memory card altogether. Most features works fine even when a memory card is not available.

What capabilities does my DSLR support?

You can ask the NikonDevice what capabilities it currently supports by calling GetCapabilityInfo. This will return a list of 'capability info' structures that describes the properties of individual capabilities.

NkMAIDCapInfo[] supportedCaps = device.GetCapabilityInfo();

// Write list of supported capabilities to the console
foreach (NkMAIDCapInfo supportedCap in supportedCaps)
{
    Console.WriteLine(supportedCap.GetDescription());
}

How do I consume capabilities?

It depends on what kind of capability it is. Below are a few examples.

NkMAIDCapInfo[] supportedCaps = device.GetCapabilityInfo();

foreach (NkMAIDCapInfo supportedCap in supportedCaps)
{
    if (supportedCap.CanStart())
    {
        // The capability is executable. Execute it by calling Start
        device.Start(supportedCap.ulID);
    }

    if (supportedCap.CanGet() && supportedCap.ulType == eNkMAIDCapType.kNkMAIDCapType_Unsigned)
    {
        // The capability is readable and its type is 'unsigned'         
        uint val = device.GetUnsigned(supportedCap.ulID);
        Console.WriteLine(supportedCap.GetDescription() + ": " + val.ToString());
    }
}

How do I set a NikonEnum capability?

First, get the NikonEnum object. Then modify the returned object and then set it again.

NikonEnum e = device.GetEnum(capability);
e.Index = 3;
device.SetEnum(capability, e);

How do I set a NikonRange capability?

First, get the NikonRange object. Then modify the returned object and then set it again.

NikonRange r = device.GetRange(capability);
r.Value = 4.3;
device.SetRange(capability, r);

How do I capture an Image?

You need to hook up to two events on the NikonDevice object. First, hook up to the ImageReady event. This event fires whenever an image is ready. Note that the ImageReady event will fire twice if you're shooting Raw+Jpeg. You should also hook up to the CaptureComplete event. This event fires when the capture is complete and no more images will be downloaded from the camera.

// Hook up events
device.ImageReady += new ImageReadyDelegate(onImageReady);
device.CaptureComplete += new CaptureCompleteDelegate(onCaptureComplete);

// Capture image
device.Capture();

...

void onImageReady(NikonDevice sender, NikonImage image)
{
    // TODO: Do something with 'image'
}

void onCaptureComplete(NikonDevice sender)
{
}

How do I record a video?

If your camera supports it, you can record a video like this.

// Hook up the 'VideoFragmentReady' event so we can receive the video after recording completes
device.VideoFragmentReady += new VideoFragmentReadyDelegate(device_VideoFragmentReady);

device.LiveViewEnabled = true;
device.StartRecordVideo();

// TODO: Wait for a while...

device.StopRecordVideo();
device.LiveViewEnabled = false;

Note that 'Live View' must be enabled while you're recording.

As you probably know, a video file can be very large - so large that it will not fit in memory. Therefore, video files are delivered in a number of smaller pieces (or fragments). Every time a new fragment is ready, your VideoFragmentReady event handler will be called.
Large videos are divided into many fragments and therefore your handler will be called multiple times (once per fragment). Your code is responsible for patching the fragments back together.

Here's an example of how to 'reassemble' a video and save it to a file.

FileStream _videoFile = null;

void device_VideoFragmentReady(NikonDevice sender, NikonVideoFragment fragment)
{
    // Open the file when we receive the first fragment
    if (fragment.IsFirst)
    {
        _videoFile = new FileStream(fragment.Filename, FileMode.Create, FileAccess.Write);
    }

    // Write the video fragment buffer to file
    _videoFile.Write(fragment.Buffer, 0, fragment.Buffer.Length);

    // Close the file when we receive the last fragment
    if (fragment.IsLast)
    {
        _videoFile.Close();
    }    
}

Why doesn't my D40, D60, D80 or D200 work on Windows 7?

These cameras are unfortunately not officially supported on Windows 7. This is NOT a limitation in the Nikon SDK C# wrapper library, but a limitation in the MD3 files from Nikon.
You should be able to debug/run your application on Windows XP or Windows Vista, but I haven't verified this personally.

One possible workaround is to use Windows 7s 'Compatibility Mode'.
Run Visual Studio in XP/Vista compatibility mode to create/debug your application. Once your application is done, make sure to run it in compatibility mode as well. Some users have reported success with this approach.

How do I get 'live view' images?

If your camera supports it, you will be able to receive the 'live view' video stream using the following method. Note that each live-view video frame is a jpeg encoded image.

device.LiveViewEnabled = true;
...
for (;;)
{
    NikonLiveViewImage img = device.GetLiveViewImage();
}
...
device.LiveViewEnabled = false;

If you want to provide a 'live view' viewer in a UI applications, for example. You typically want to call GetLiveViewImage from a timer, perhaps a DispatcherTimer. The project source code includes a WPF example application that demonstrates this.

I can't find an MD3 file for my (old) camera on Nikon's website - What can I do?

See [Finding MD3 Files For Old Cameras]

Does the library work with VB.NET too?

Yes - the library works with all .NET based languages. Including VB.NET.

Can I connect multiple cameras to the same PC?

If you plan on connecting multiple different camera models, all of which use different MD3 files, then yes!
I've successfully controlled a D90, a D5100 and a D7000 simultaneously from a single application. So I know this works.

Unfortunately, connecting two (or more) identical cameras, such as two D7000s does not work. This appears to be a limitation in the Nikon SDK: Each MD3 file can only handle ONE device at the time within the same process.

A possible workaround for this would be to build a process isolation system, where each camera is controlled from a dedicated process. You would have design an inter-process communication scheme to transfer data to and from these controller processes. This is a feature that could possibly make it into the wrapper in the future, but for now no such functionality is supported.

What is a SessionFailure exception?

I'm not 100% sure why this is happening. All I know is that when it happens the SDK usually becomes useless and the only way to fix it is to:
1. Restart the 'Windows Image Acquisition (WIA)' service or
2. Reboot your PC (which effectively achieves the same)

According to Nikon's documentation:

The module cannot open source object because the camera cannot open more session.
The camera can open 1 session. If the client tries to open more source object, the
module returns this error.

Edit: Through convoluted ways, I managed to get in contact with the Nikon SDK engineers. They confirmed that SessionFailures are caused by multiple open sessions and that this error state is un-recoverable, meaning that restarting the WIA service is the only way to recover from this.

There are a few things that seem to influence the frequency of SessionFailure exceptions.

  1. Make sure to call the Shutdown() function on your NikonManager object before terminating your application. This is easy to forget during development and debugging. Forgetting to call Shutdown() leaves the 'source' object open and seems to increase the probability of SessionFailures.

  2. Make sure to use the USB cable that came with your Nikon DSLR. Using any other cable than the one supplied by Nikon seems to increase the probability of SessionFailure exceptions.

  3. Do not use any USB hubs/switches. Connect the camera directly to your PC.

  4. Make sure you have the latest drivers for your USB controller.

  5. Try connecting your camera to a different USB port on your PC.


Related

Discussion: Workaround older Cameras on Windows 7
Discussion: Set NikonEnum Propertie Workaround
Wiki: Finding MD3 Files For Old Cameras
Wiki: Home

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks