(들어가기전에 -> 이미지를 순수하게 전송할수는 없고 base64를 사용하여 디코드 인코드 하여야 합니다.)
1. Publisher Code
간단 알고리즘 설명 : 사진찍음 → 찍은사진 1장 폴더에 저장→ 폴더에 있는 파일 open함→ image파일을 인코딩함 → 인코딩된 것을 변수로 할당받음→ 할당받은 변수를 mqtt전송함.
주의 ※ base64사용시 약 130% 용량이 증가함. 게다가 이미지의 화소가 높으면 인코딩시
str형식이던 byte형식이던 너무 길어짐으로 mqtt전송에 딜레이가 심하고 전송이 거의 안됨.
즉, 찍히는 사진 크기 줄여서 사진을 찍으세요
※ 상대경로 절대경로 설정
※ 다시한번 말한다 , QOS Level은 일치해야한다. (나는 rabbitmq써서 qos level 2지원안함...)
import paho.mqtt.client as mqtt
import base64
import os
import sys
import picamera
import datetime
from time import sleep
savepath='/home/pi/project_3/picturesave' # 사직이 찍히면 저장되는 '절대 경로'
readpath='./project_3/picturesave/' # 찍힌 사진의 폴더 내용물 읽는 '상대경로'
# 저장된 폴더에 이미지 삭제하는 함수.
def delete_All_files(filePath):
if os.path.exists(filePath):
for file in os.scandir(filePath):
os.remove(file.path)
# 라즈베리파이 카메라 캡쳐 하는 함수
def kickcameraCapture():
with picamera.PiCamera() as camera:
now=datetime.datetime.now()
filename=now.strftime('%m%d-%H%M%S')
camera.resolution = (320, 240) # 촬영되는 사진 크기 (크면 인코딩시 이미지 길이 길어져서 에러남.)
camera.framerate = 5
camera.start_preview()
sleep(1) # 몇 초 간격으로 찍을지.
camera.stop_preview()
camera.capture(output=savepath+'/'+filename+'.jpg')
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("connected OK")
else:
print("Bad connection Returned code=", rc)
def on_disconnect(client, userdata, flags, rc=0):
print(str(rc))
def on_publish(client, userdata, mid):
print("In on_pub callback mid= ", mid)
# 새로운 클라이언트 생성
client = mqtt.Client()
# 콜백 함수 설정 on_connect(브로커에 접속), on_disconnect(브로커에 접속중료), on_publish(메세지 발행)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish
# address : 111.111.111.119, port: 1883 에 연결
client.connect('111.111.111.119',20518)
client.loop_start()
#kickcameraCapture()
while True:
delete_All_files(savepath)
kickcameraCapture()
file_directory=os.listdir(readpath)
myfile='filename.jpg'
for filename in file_directory:
if filename == myfile:
continue
with open(readpath+filename, 'rb') as img:
image_read = img.read()
img_encoding = base64.b64encode(image_read) # bytes형식임.
clean=img_encoding.decode('ascii') # str형식으로 변환해줌.
client.publish('image_4',clean,1) # str형식으로 넘어감.(어떤 형식으로 넘기던 상관없더라)
# 용량차이 미비함.
client.loop_stop()
# 연결 종료
client.disconnect()
- 1. 저장된 폴더에 이미지 삭제하는 함수.
라즈베리파이 공식홈페이지에서 API를 읽어봤지만 그 어디에도.. 찍히면 폴더에 저장이 되는 기능밖에 가능하지
않았다. 즉 사진을 찍고, 찍힌 사진을 바로 인코딩을 구현은 불가능 하다는 것이다.
주의) filePath 는 '절대경로'임
- 2. 라즈베리파이 카메라 캡쳐하는 함수.
말그대로 함수 실행시 카메라가 작동하며 우리가 지정한 디렉토리에 파일이 '날짜명.jpg' 형식으로 저장됨.
- 3. 폴더안에서 있는 파일 불러오는 코드.
readpath(상대경로)에 있는 모든 파일들을 리스트 형식으로 불러옴. 불러온 리스트상의 파일들중에 ' .jpg ' 라고
되어있는 확장자만 일치하면 continue 가 작동함.
- 4. ' bytes형식 ' or ' str형식 ' 으로 인코딩
bytes형식이던 str형식이던 어떤 형식으로 보내던 상관없다. 둘다 잘 동작함(물론 용량을 찍어보니 bytes가 매우
조금 더 라이트 했다)
2. Subscriber Code
->그냥 똑같다...
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("connected OK")
else:
print("Bad connection Returned code=", rc)
def on_disconnect(client, userdata, flags, rc=0):
print(str(rc))
def on_subscribe(client, userdata, mid, granted_qos):
print("subscribed: " + str(mid) + " " + str(granted_qos))
def on_message(client, userdata, msg):
print(str(msg.payload.decode("utf-8")))
# 새로운 클라이언트 생성
client = mqtt.Client()
# 콜백 함수 설정 on_connect(브로커에 접속), on_disconnect(브로커에 접속중료), on_subscribe(topic 구독),
# on_message(발행된 메세지가 들어왔을 때)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_subscribe = on_subscribe
client.on_message = on_message
# address : localhost, port: 20518 에 연결
client.connect('localhost', 20518)
client.subscribe('image_4',1) ## QOS 자체설정 주의 0 or 1
client.loop_forever()
아래와 같은 출력물이 터미널에 나오게 된다....(더 긴데 짤림..)
(뭔가 무서운데?..)
그렇다면 이제 어?..나는 이미지가 필요한건데..
결국..-> 이받은 데이터를 인코딩을 하면 되는것이다.
import base64
from PIL import Image
from io image BytesIO
import matplotlib.pyplot as plt
img = Image.open(BytesIO(base64.b64decode(base64_string))) # 디코딩한 string이 들어가면 됨.
plt.imshow(img)
-------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- ---
DB를 사용하는 방법은 이전 게시물(Gyro) 에서 설명을 하였다..(DB부분 빼버림..) -> 링크: https://put-idea.tistory.com/43
'프로그래밍 > MQTT' 카테고리의 다른 글
[Python] MQTT를 이용한 GPS 값 전송 (raspberry pi 이용) (0) | 2022.09.05 |
---|---|
[Python] MQTT를 이용한 자이로센서 값 전송 (raspberry pi 이용) (0) | 2022.08.15 |
[Python] MQTT 통신하기(docker,rabbitmq사용) (0) | 2022.08.12 |
(4) MQTT.fx 사용하기 (0) | 2022.03.01 |
(3) 파이썬에서 MQTT 사용하기. (0) | 2022.03.01 |