dukus / digiCamControl

DSLR camera remote control open source software
http://digicamcontrol.com/
Other
675 stars 226 forks source link

TransportInMemory not used for Canon #343

Open thanossv opened 4 years ago

thanossv commented 4 years ago

Hi, I have used the CameraControl.Devices.Example for a project. After the application captures a picture, it uploads it to a server.

Two of the necessary requirements are:

To get the stream of a photo from Nikon, I used with success the following code:

MemoryStream cameraStream = new MemoryStream();
log.Debug("created 1st stream");
eventArgs.CameraDevice.TransferFile(eventArgs.Handle, cameraStream);

However, when the same piece of code ran for Canon, I got the following error:

2020-03-11 13:14:29 DEBUG Form1:250 - created 1st stream
2020-03-11 13:14:29 ERROR Form1:274 - Error download photo from camera :
Unable to cast object of type 'System.IntPtr' to type 'System.IConvertible'.

Upon investigation, since the CameraDevice depends on the used SDK, the TransferFile method used for Canon is this one.

The only TransferFile method that uses the TransferToFile for EOS can be found here.

It seems that in order for Canon to work entirely without creating any files, a method of this signature needs to be added in CanonSDKBase.cs: public override void TransferFile(object o, Stream stream) that will use public EosMemoryImageEventArgs TransportInMemory(IntPtr directoryItem, IntPtr context) (currently not used in any place if my search was correct)

My questions are:

  1. is there any existing TransferFile method to use for Canon, that I may have missed?
  2. if not, was it intended or it is coming to a future version?

I've made some attempts to create a TransferFile using stream, but without luck so far, I need to dig deeper. But I also wanted to get some feedback from you for my case.

Thanks in advance! Thanos

mathcham commented 4 years ago

Hi, I also had this problem just yesterday for my Canon EOS R, trying to keep the files in memory via stream. I created the override TransferFile(...) and it now works after recompiling CameraControl.Device.

I added the following function to CanonSDKBase.cs :

public override void TransferFile(object o, Stream stream)
        {
            // Sanity checks.
            if (!stream.CanWrite)
                throw new ArgumentException("Specified stream is not writable.", "stream");
            lock (Locker)
            {
                IsBusy = true;
                if (o is IntPtr)
                {
                    Log.Debug("Pointer file transfer started");
                    try
                    {
                        IsBusy = true;
                        Camera.PauseLiveview();
                        Log.Debug("Camera.PauseLiveview();");
                        var transporter = new EosImageTransporter();
                        transporter.ProgressEvent += (i) => TransferProgress = (uint)i;
                        Log.Debug("TransportInMemory");
                        EosImageEventArgs imageEvent = transporter.TransportInMemory((IntPtr)o, Camera.Handle);
                        imageEvent.GetStream().CopyTo(stream);
                        Log.Debug("TransportInMemory DONE");
                        Camera.ResumeLiveview();
                        Log.Debug("Camera.ResumeLiveview(); DONE");
                    }
                    catch (Exception exception)
                    {
                        Log.Error("Error transfer memory file", exception);
                        //File.Delete(filename);
                    }
                }
            }
        }

It probably wont work with every Canon camera on the market as I suppose they have different structures/API.

mathcham