Python Forum
Controling a Canon dslr camera on Windows
Thread Rating:
  • 1 Vote(s) - 4 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Controling a Canon dslr camera on Windows
#11
from ctypes import *
import pythoncom
import datetime

edsdk = windll.edsdk


def AddTime(fname):
    now = datetime.datetime.now()
    nname = fname[:-4]+'_'+now.isoformat()[:-7].replace(':','-')+fname[-4:]
    return nname


class EDSDKError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

def EDErrorMsg(code):
	return "EDSDK error code"+hex(code)
	
def Call(code):
	if code!=0:
            raise EDSDKError,EDErrorMsg(code)
		
def Release(ref):
	edsdk.EdsRelease(ref)
	
def GetChildCount(ref):
	i = c_int()
	Call(edsdk.EdsGetChildCount(ref,byref(i)))
	return i.value

def GetChild(ref,number):
	c = c_void_p()
	Call(edsdk.EdsGetChildAtIndex(ref,number,byref(c)))
	return c
	

kEdsObjectEvent_DirItemRequestTransfer  =    0x00000208
kEdsObjectEvent_DirItemCreated       =       0x00000204


ObjectHandlerType = WINFUNCTYPE   (c_int,c_int,c_void_p,c_void_p)
def ObjectHandler_py(event,object,context):
	if event==kEdsObjectEvent_DirItemRequestTransfer:
		DownloadImage(object)
	return 0
ObjectHandler = ObjectHandlerType(ObjectHandler_py)


kEdsStateEvent_WillSoonShutDown       =      0x00000303

StateHandlerType = WINFUNCTYPE   (c_int,c_int,c_int,c_void_p)
def StateHandler_py(event,state,context):
	if event==kEdsStateEvent_WillSoonShutDown:
		print ("cam about to shut off")
		Call(edsdk.EdsSendCommand(context,1,0))
	return 0
StateHandler = StateHandlerType(StateHandler_py)


PropertyHandlerType = WINFUNCTYPE   (c_int,c_int,c_int,c_int,c_void_p)
def PropertyHandler_py(event,property,param,context):
	return 0
PropertyHandler = PropertyHandlerType(PropertyHandler_py)


class DirectoryItemInfo(Structure):
	_fields_ = [("size", c_int),
				("isFolder", c_int),
				("groupID",c_int),
				("option",c_int),
				("szFileName",c_char*256),
				("format",c_int)]

WaitingForImage = False
ImageFilename = None

def DownloadImage(image):
	dirinfo = DirectoryItemInfo()
	Call(edsdk.EdsGetDirectoryItemInfo(image,byref(dirinfo)))
	stream = c_void_p()
	global ImageFilename
	if ImageFilename is None:
		print ("Image was taken manually")
		ImageFilename = AddTime("IMG.jpg")
	print ("Saving as"),ImageFilename
	Call(edsdk.EdsCreateFileStream(ImageFilename,1,2,byref(stream)))
	
	Call(edsdk.EdsDownload(image,dirinfo.size,stream))
	Call(edsdk.EdsDownloadComplete(image))
	Release(stream)
	
	global WaitingForImage
	WaitingForImage = False


kEdsSaveTo_Camera       =   1
kEdsSaveTo_Host         =   2
kEdsSaveTo_Both         =   kEdsSaveTo_Camera | kEdsSaveTo_Host
kEdsPropID_SaveTo  = 0x0000000b



class EdsCapacity(Structure):
	_fields_ = [("numberOfFreeClusters", c_int),
				("bytesPerSector", c_int),
				("reset",c_int)]


class Camera:
	def __init__(self,camnum=0):
		self.cam = None
		l = CameraList()
		self.cam = l.GetCam(camnum)
		Call(edsdk.EdsSetObjectEventHandler(self.cam,0x200,ObjectHandler,None))
		Call(edsdk.EdsSetPropertyEventHandler(self.cam,0x100,PropertyHandler,None))
		Call(edsdk.EdsSetCameraStateEventHandler(self.cam,0x300,StateHandler,self.cam))
		Call(edsdk.EdsOpenSession(self.cam))
		
		self.SetProperty(kEdsPropID_SaveTo,kEdsSaveTo_Host)
		
		# set large capacity
		cap = EdsCapacity(10000000,512,1)
		Call(edsdk.EdsSetCapacity(self.cam,cap))
	def __del__(self):
		if self.cam is not None:
			Call(edsdk.EdsCloseSession(self.cam))
			Call(Release(self.cam))
	def SetProperty(self,property,param):
		d = c_int(param)
		Call(edsdk.EdsSetPropertyData(self.cam,property,0,4,byref(d)))
	def AutoFocus(self):
#	kEdsCameraCommand_ShutterButton_OFF					= 0x00000000,
#	kEdsCameraCommand_ShutterButton_Halfway				= 0x00000001,
#	kEdsCameraCommand_ShutterButton_Completely			= 0x00000003,
#	kEdsCameraCommand_ShutterButton_Halfway_NonAF		= 0x00010001,
#	kEdsCameraCommand_ShutterButton_Completely_NonAF	= 0x00010003,
		# note that this can fail when AF fails (error code 0x8D01)
		self.SendCommand(4,1)
	def Shoot(self,fname=None):
		# set saving flag
		global WaitingForImage
		WaitingForImage = True

		# set filename
		global ImageFilename
		if fname is None:
			ImageFilename = AddTime("IMG.jpg")
		else:
			ImageFilename = fname

		# note that this can fail when AF fails (error code 0x8D01)
		self.SendCommand(0)
		# capture succeeded so go on to download image
		while WaitingForImage:
			pythoncom.PumpWaitingMessages()
		return ImageFilename
	def KeepOn(self):
		# important command - keeps the camera connected when not used
		self.SendCommand(1)
	def SendCommand(self,command,param=0):
		#define kEdsCameraCommand_TakePicture                     0x00000000
		#define kEdsCameraCommand_ExtendShutDownTimer             0x00000001
		#define kEdsCameraCommand_BulbStart						  0x00000002 
		#define kEdsCameraCommand_BulbEnd						  0x00000003 
		#define kEdsCameraCommand_DoEvfAf                         0x00000102
		#define kEdsCameraCommand_DriveLensEvf                    0x00000103
		#define kEdsCameraCommand_DoClickWBEvf                    0x00000104		
		#define kEdsCameraCommand_PressShutterButton			  0x00000004
		Call(edsdk.EdsSendCommand(self.cam,command,param))

class CameraList:
	def __init__(self):
		self.list = c_void_p(None)
		Call(edsdk.EdsGetCameraList(byref(self.list)))
		print ("found"),GetChildCount(self.list),"cameras"
	def Count(self):
		return GetChildCount(self.list)
	def GetCam(self,number=0):
		print ("get cam")
		#if self.Count()<(number+1):
			#raise ValueError,"Camera not found, make sure it's on and connected"
		return GetChild(self.list,number)
	def __del__(self):
		Release(self.list)
	
edsdk.EdsInitializeSDK()

if __name__=="__main__":
	pythoncom.CoInitialize()
	c = Camera()
	from time import sleep

	c.Shoot()
	
	sleep(5)
	
	c.AutoFocus()
	c.Shoot()
	
	del c
	
	edsdk.EdsTerminateSDK()

	sleep(2)

 raise EDSDKError,EDErrorMsg(code)
This line give the invalid syntax error
Reply
#12
for python 3 I believe this should be:
    raise Exception(EDSDKError, EDErrorMsg(code))
Reply
#13
Thank you.
I was forgotten that it was written in Python 2.
The new problem is:
I can make a picture only when it download the image to the pc i get this error:


Error:
Traceback (most recent call last): File "_ctypes/callbacks.c", line 234, in 'calling callback function' File "C:\Users\Leond\Desktop\printmap\EDSDKv0306-1W\EDSDKv0306-1W\Windows\EDSDK_64\Dll\canonsdk.py", line 48, in ObjectHandler_py DownloadImage(object) File "C:\Users\Leond\Desktop\printmap\EDSDKv0306-1W\EDSDKv0306-1W\Windows\EDSDK_64\Dll\canonsdk.py", line 83, in DownloadImage Call(edsdk.EdsGetDirectoryItemInfo(image,byref(dirinfo))) ctypes.ArgumentError: argument 1: <class 'OverflowError'>: int too long to convert
Reply
#14
I can only help with basic connectivity issues.
I know nothing about windll.edsdk.
Googling finds: https://sourceforge.net/projects/pycanon/
Can't find much else, you might have to look at https://github.com/andrewrk/pyedsdk
(modified last 7 years ago) and convert to python 3
Reply
#15
It was a 64 bit versus 32 bit issue.

With python 32 bit it works.

Only there is another error now.

Error:
Traceback (most recent call last): File "_ctypes/callbacks.c", line 232, in 'calling callback function' File "C:\Users\Leond\Desktop\printmap\EDSDKv0306-1W\EDSDKv0306-1W\Windows\EDSDK\Dll\canonsdk.py", line 48, in ObjectHandler_py DownloadImage(object) File "C:\Users\Leond\Desktop\printmap\EDSDKv0306-1W\EDSDKv0306-1W\Windows\EDSDK\Dll\canonsdk.py", line 92, in DownloadImage Call(edsdk.EdsDownload(image,dirinfo.size,stream)) ValueError: Procedure probably called with not enough arguments (4 bytes missing)
from ctypes import *
import pythoncom
import datetime

edsdk = windll.edsdk


def AddTime(fname):
    now = datetime.datetime.now()
    nname = fname[:-4]+'_'+now.isoformat()[:-7].replace(':','-')+fname[-4:]
    return nname


class EDSDKError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

def EDErrorMsg(code):
    return "EDSDK error code"+hex(code)
    
def Call(code):
    if code!=0:
            raise Exception(EDSDKError, EDErrorMsg(code))
        
def Release(ref):
    edsdk.EdsRelease(ref)
    
def GetChildCount(ref):
    i = c_int()
    Call(edsdk.EdsGetChildCount(ref,byref(i)))
    return i.value

def GetChild(ref,number):
    c = c_void_p()
    Call(edsdk.EdsGetChildAtIndex(ref,number,byref(c)))
    return c
    

kEdsObjectEvent_DirItemRequestTransfer  =    0x00000208
kEdsObjectEvent_DirItemCreated       =       0x00000204


ObjectHandlerType = WINFUNCTYPE   (c_int,c_int,c_void_p,c_void_p)
def ObjectHandler_py(event,object,context):
    if event==kEdsObjectEvent_DirItemRequestTransfer:
        DownloadImage(object)
    return 0
ObjectHandler = ObjectHandlerType(ObjectHandler_py)


kEdsStateEvent_WillSoonShutDown       =      0x00000303

StateHandlerType = WINFUNCTYPE   (c_int,c_int,c_int,c_void_p)
def StateHandler_py(event,state,context):
    if event==kEdsStateEvent_WillSoonShutDown:
        print ("cam about to shut off")
        Call(edsdk.EdsSendCommand(context,1,0))
    return 0
StateHandler = StateHandlerType(StateHandler_py)


PropertyHandlerType = WINFUNCTYPE   (c_int,c_int,c_int,c_int,c_void_p)
def PropertyHandler_py(event,property,param,context):
    return 0
PropertyHandler = PropertyHandlerType(PropertyHandler_py)


class DirectoryItemInfo(Structure):
    _fields_ = [("size", c_int),
                ("isFolder", c_int),
                ("groupID",c_int),
                ("option",c_int),
                ("szFileName",c_char*256),
                ("format",c_int)]

WaitingForImage = False
ImageFilename = None

def DownloadImage(image):
    dirinfo = DirectoryItemInfo()
    Call(edsdk.EdsGetDirectoryItemInfo(image,byref(dirinfo)))
    stream = c_void_p()
    global ImageFilename
    if ImageFilename is None:
        print ("Image was taken manually")
        ImageFilename = AddTime("IMG.jpg")
    print ("Saving as"),ImageFilename
    Call(edsdk.EdsCreateFileStream(ImageFilename,1,2,byref(stream)))
    
    Call(edsdk.EdsDownload(image,dirinfo.size,stream))
    Call(edsdk.EdsDownloadComplete(image))
    Release(stream)
    
    global WaitingForImage
    WaitingForImage = False


kEdsSaveTo_Camera       =   1
kEdsSaveTo_Host         =   2
kEdsSaveTo_Both         =   kEdsSaveTo_Camera | kEdsSaveTo_Host
kEdsPropID_SaveTo  = 0x0000000b



class EdsCapacity(Structure):
    _fields_ = [("numberOfFreeClusters", c_int),
                ("bytesPerSector", c_int),
                ("reset",c_int)]


class Camera:
    def __init__(self,camnum=0):
        self.cam = None
        l = CameraList()
        self.cam = l.GetCam(camnum)
        Call(edsdk.EdsSetObjectEventHandler(self.cam,0x200,ObjectHandler,None))
        Call(edsdk.EdsSetPropertyEventHandler(self.cam,0x100,PropertyHandler,None))
        Call(edsdk.EdsSetCameraStateEventHandler(self.cam,0x300,StateHandler,self.cam))
        Call(edsdk.EdsOpenSession(self.cam))
        
        self.SetProperty(kEdsPropID_SaveTo,kEdsSaveTo_Host)
        
        #set large capacity
        cap = EdsCapacity(10000000,512,1)
        Call(edsdk.EdsSetCapacity(self.cam,cap))
    def __del__(self):
        if self.cam is not None:
            Call(edsdk.EdsCloseSession(self.cam))
            Call(Release(self.cam))
    def SetProperty(self,property,param):
        d = c_int(param)
        Call(edsdk.EdsSetPropertyData(self.cam,property,0,4,byref(d)))
    def AutoFocus(self):
#   kEdsCameraCommand_ShutterButton_OFF                 = 0x00000000,
#   kEdsCameraCommand_ShutterButton_Halfway             = 0x00000001,
#   kEdsCameraCommand_ShutterButton_Completely          = 0x00000003,
#   kEdsCameraCommand_ShutterButton_Halfway_NonAF       = 0x00010001,
#   kEdsCameraCommand_ShutterButton_Completely_NonAF    = 0x00010003,
        # note that this can fail when AF fails (error code 0x8D01)
        self.SendCommand(4,1)
    def Shoot(self,fname=None):
        # set saving flag
        global WaitingForImage
        WaitingForImage = True

        # set filename
        global ImageFilename
        if fname is None:
            ImageFilename = AddTime("IMG.jpg")
        else:
            ImageFilename = fname

        # note that this can fail when AF fails (error code 0x8D01)
        self.SendCommand(0)
        # capture succeeded so go on to download image
        while WaitingForImage:
            pythoncom.PumpWaitingMessages()
        return ImageFilename
    def KeepOn(self):
        # important command - keeps the camera connected when not used
        self.SendCommand(1)
    def SendCommand(self,command,param=0):
        #define kEdsCameraCommand_TakePicture                     0x00000000
        #define kEdsCameraCommand_ExtendShutDownTimer             0x00000001
        #define kEdsCameraCommand_BulbStart                       0x00000002 
        #define kEdsCameraCommand_BulbEnd                         0x00000003 
        #define kEdsCameraCommand_DoEvfAf                         0x00000102
        #define kEdsCameraCommand_DriveLensEvf                    0x00000103
        #define kEdsCameraCommand_DoClickWBEvf                    0x00000104        
        #define kEdsCameraCommand_PressShutterButton              0x00000004
        Call(edsdk.EdsSendCommand(self.cam,command,param))

class CameraList:
    def __init__(self):
        self.list = c_void_p(None)
        Call(edsdk.EdsGetCameraList(byref(self.list)))
        print ("found"),GetChildCount(self.list),"cameras"
    def Count(self):
        return GetChildCount(self.list)
    def GetCam(self,number=0):
        print ("get cam")
        #if self.Count()<(number+1):
            #raise ValueError,"Camera not found, make sure it's on and connected"
        return GetChild(self.list,number)
    def __del__(self):
        Release(self.list)
    
edsdk.EdsInitializeSDK()

if __name__=="__main__":
    pythoncom.CoInitialize()
    c = Camera()
    from time import sleep

    c.Shoot()
    
    #sleep(5)
    
    #c.AutoFocus()
    #c.Shoot()
    
    del c
    
    edsdk.EdsTerminateSDK()

    sleep(2)
Whats wrong ??
Reply
#16
@Leon, I know this is a bit old at this point, but have you figured out how to solve this? I am having the same error pop up, and I'm stuck on how to fix it.
Reply
#17
Quote:I know this is a bit old at this point
Last visit was July, this post almost 1 year old, very unlikely it will be read by OP.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Get image from PI camera and analyze it korenron 0 1,164 Apr-28-2022, 06:49 AM
Last Post: korenron
  Create RTSP stream from camera? korenron 1 3,262 Jan-04-2022, 10:38 AM
Last Post: Larz60+
  How to get OpenCV to display entire camera frame? George713 1 3,266 Aug-12-2021, 02:45 AM
Last Post: Pedroski55
  Wifi Camera Connection MeenAg 2 3,112 Oct-02-2020, 06:35 PM
Last Post: MeenAg
  mapping-camera-coordinates-to-a-2d-floor-plan fauveboyxuuki 0 2,542 Dec-10-2019, 10:34 PM
Last Post: fauveboyxuuki
  New to Python, help with saving image from camera tantony 2 3,854 Sep-13-2019, 05:19 PM
Last Post: tantony
  pi camera stream is upside down delta1071 3 5,750 Sep-11-2019, 11:35 AM
Last Post: metulburr
  Camera animation to Text file (CINEMA 4D) vbz 0 2,309 Aug-13-2019, 07:39 AM
Last Post: vbz
  How to extract temperature value of pixels of a thermal image recorded by IR camera hamacvan 1 14,454 Jan-13-2019, 06:06 PM
Last Post: Larz60+
  Camera Image Data annakin4 0 2,657 Jan-24-2018, 05:50 PM
Last Post: annakin4

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020