前回はカメラのプレビュー画面をWebに表示させましたが、
今回はWebからシャッターボタンを設置して、カメラの画像を保存させます。
すでにPOSTリクエストを処理する方法も知っていますし、カメラの画像を保存する方法も知っているので、これらを組み合わせればできるはずです。
まずはサーバ(ラズパイ)の処理。
def do_POST(self):
content_len = int(self.headers.get('content-length'))
requestBody = json.loads(self.rfile.read(content_len).decode('utf-8'))
if requestBody['contents']['command'] == 1:
_, img = cap.read()
dt_now = datetime.datetime.now()
filename = dt_now.strftime('%Y%m%d_%H%M%S')+".jpg"
cv2.imwrite(filename, img)
response = {
'status' : 200,
'path': "http://pi4.local:8000/" + filename
}
else:
response = {
'status' : 200
}
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
responseBody = json.dumps(response)
self.wfile.write(responseBody.encode('utf-8'))
POST処理を追加しました。
カメラの画像をファイルに保存し、そのファイルパスをレスポンスで返すようなイメージです。
次はWeb側。
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="vue.min.js"></script>
<script src="jquery-3.5.1.slim.min.js"></script>
</head>
<body>
<div id="app">
<image id="camera" src="" /><br />
<button @click="onShutter">Shutter</button><br />
<a id="picture" href="" target="_blank">{{ path }}</a>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
timer: null,
param: {},
contents: {
command: 1,
},
path: "",
},
created: function() {
self = this;
this.timer = setInterval(function() {self.onLoad()}, 50)
},
methods: {
onLoad: function() {
axios.get('http://pi4.local:8000/Streaming').then(function(response){
$("#camera").attr('src', response.data.image);
}).catch(function(error){
});
},
onShutter: function() {
self = this;
this.param.contents = this.contents;
axios.post('http://pi4.local:8000/', this.param).then(function(response){
$("#picture").attr('href', response.data.path);
self.path = response.data.path;
}).catch(function(error){
});
}
}
})
</script>
</body>
</html>
ボタンとリンクを追加しました。
ボタンをクリックすると、onShutter処理が実行され、ラズパイ側にPOSTリクエストを送信します。
そのレスポンスから画像のファイルパスを取得し、リンクに反映させます。
同じ仕組みで動画の撮影もできそう。
次回やります。