forked from digitaltrails/piKam
-
Notifications
You must be signed in to change notification settings - Fork 0
/
piKamPicamServer.py
135 lines (115 loc) · 5.91 KB
/
piKamPicamServer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# -*- coding: utf-8 -*-
#!/usr/bin/env python
#
# PiKamPicamServer.py - Picam server for PiKam
#
# Copyright (C) 2013: Michael Hamilton
# The code is GPL 3.0(GNU General Public License) ( http://www.gnu.org/copyleft/gpl.html )
#
from twisted.internet import reactor, protocol, defer
import cPickle as Pickler
from datetime import datetime
import StringIO
import picam
from piKamCommon import SCENE_OPTIONS,AWB_OPTIONS,METERING_OPTIONS,IMXFX_OPTIONS,COLFX_OPTIONS,ISO_OPTIONS,ENCODING_OPTIONS
from piKamServer import PiKamServerProtocal
class PiKamPicamServerProtocal(PiKamServerProtocal):
shooting = False
# Max message/jpg size.
MAX_LENGTH = 100000000
def stringReceived(self, data):
"""Process decoded Netstring message received from a client."""
# Turn the received string back into a dictionary.
#print data
cmd = Pickler.loads(data)
# Retreive the command from the dictionary
if cmd['cmd'] == 'shoot':
imageFilename, image, imageType, replyMessageType = self.takePhoto(cmd['args'])
self.transmitPhoto(imageFilename, image, imageType, replyMessageType)
elif cmd['cmd'] == 'prepareCamera':
self.prepareCamera(cmd)
else:
print 'bad message', cmd['cmd']
msg = 'Invalid Command:' + cmd['cmd']
self.transport.write(str(len(msg)) + ':' + msg + ',')
def connectionLost(self, reason):
print "Client Connection Lost!"
def prepareCamera(self, cmd):
"""Put the camera in to recording mode."""
#self.osCommand(['/home/pi/chdkptp.sh', '-econnect', '-erec'])
pass
def transmitPhoto(self, imageFilename, image, imageType, replyMessageType):
#print imageFilename, str(len(imageBinary))
buffer = StringIO.StringIO()
image.save(buffer, imageType)
imageBinary = buffer.getvalue()
buffer.close()
print replyMessageType, imageType, 'imgsz=', str(len(imageBinary))
if imageBinary:
data = {'type':replyMessageType, 'name':imageFilename, 'data':imageBinary}
else:
print 'error'
data = {'type':'error', 'message':'Problem reading captured file.'}
# data = {'type':'error', 'message':'Problem during capture.'}
# Turn the dictionary into a string so we can send it in Netstring format.
message = Pickler.dumps(data, Pickler.HIGHEST_PROTOCOL)
# Return a Netstring message to the client - will include the jpeg if all went well
#self.transport.write(str(len(message)) + ':' + message + ',')
self.transport.write(str(len(message)))
self.transport.write(':')
self.transport.write(message)
self.transport.write(',')
def takePhoto(self, parameters):
while self.shooting:
print 'sleeping'
self._sleep(1)
try:
self.shooting = True
request = parameters
#print vars(request)
imageType = request.encoding if request.encoding else 'jpg'
imageFilename = 'IMG-' + datetime.now().isoformat().replace(':','_') + '.' + imageType
imageType = request.encoding if request.encoding != 'jpg' else 'JPEG'
replyType = request.replyMessageType
#print imageType, imageFilename
picam.config.imageFX = IMXFX_OPTIONS.index(request.imxfx) if request.imxfx else 0
picam.config.exposure = SCENE_OPTIONS.index(request.scene) if request.scene else 0
picam.config.meterMode = METERING_OPTIONS.index(request.metering)
picam.config.awbMode = AWB_OPTIONS.index(request.awb)
picam.config.ISO = int(request.iso) if ISO_OPTIONS.index(request.iso) != 0 else 0
picam.config.sharpness = int(request.sharpness) if request.sharpness else 0 # -100 to 100
picam.config.contrast = int(request.contrast) if request.contrast else 0 # -100 to 100
picam.config.brightness = int(request.brightness) if request.brightness else 0 # 0 to 100
picam.config.saturation = int(request.saturation) if request.saturation else 0 # -100 to 100
#picam.config.videoStabilisation = 0 # 0 or 1 (false or true)
# EV seems to be mis-stated - adjust
picam.config.exposureCompensation = int(request.ev * 8) if request.ev else 0 # -10 to +10 ?
#print picam.config.exposureCompensation
#picam.config.rotation = 90 # 0-359
picam.config.hflip = int(request.hflip) if request.hflip else 0 # 0 or 1
picam.config.vflip = int(request.vflip) if request.vflip else 0 # 0 or 1
#picam.config.shutterSpeed = 20000 # 0 = auto, otherwise the shutter speed in ms
width = request.width if request.width else self.MAX_WIDTH
height = request.height if request.height else self.MAX_HEIGHT
quality = int(request.quality) if request.quality else self.DEFAULT_QUALITY
if request.zoomTimes > 1.0:
sz = 1.0/request.zoomTimes
picam.config.roi = [ .5 - sz/2.0, .5 - sz/2.0, sz, sz ]
#print picam.config.roi
image = picam.takePhotoWithDetails(width,height,quality)
#print imageFilename, str(len(imageBinary))
return imageFilename, image, imageType, replyType
finally:
self.shooting = False
def _sleep(secs):
d = defer.Deferred()
reactor.callLater(secs, d.callback, None)
return d
def main():
"""This runs the protocol on port 8000"""
factory = protocol.ServerFactory()
factory.protocol = PiKamPicamServerProtocal
reactor.listenTCP(8000,factory)
reactor.run()
if __name__ == '__main__':
main()