From 5abb91bffb3b3832dbc955cf16224b3d8da34a18 Mon Sep 17 00:00:00 2001 From: CalisJI Date: Thu, 22 Aug 2024 09:31:26 +0700 Subject: [PATCH] Updare README --- README.md | 203 ++++++++++++++++++++++++++++++++++++++++++++++ img/connector.jpg | Bin 0 -> 31451 bytes 2 files changed, 203 insertions(+) create mode 100644 README.md create mode 100644 img/connector.jpg diff --git a/README.md b/README.md new file mode 100644 index 0000000..490c644 --- /dev/null +++ b/README.md @@ -0,0 +1,203 @@ +# Project stream frame via websocket using ESP32 to LED Panel 128x128 + +### Pinout +![](/img/connector.jpg) + + +### Example code to send image/gif.video... to ESP32 + +```python +from PIL import Image, ImageSequence +import socket +import struct +import time +import cv2 +import serial +from flask import Flask, request, redirect, make_response +import os +import asyncio +import websockets +import threading +### Flask configuration +app = Flask(__name__) +UPLOAD_FOLDER = 'uploads' +RESIZED_FOLDER = 'resized' +os.makedirs(UPLOAD_FOLDER, exist_ok=True) +os.makedirs(RESIZED_FOLDER, exist_ok=True) + +### Socket configuration +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +udp_ip = '192.168.2.243' # IP của ESP32 +udp_port = 5000 +uri = "ws://192.168.2.243:81" +media_path = '/home/qthi/Documents/quyth/Image/128x128/gif2.gif' + +# To manage the WebSocket thread +websocket_thread = None +websocket_stop_event = threading.Event() + +### Page +@app.route('/') +def upload_form(): + return ''' + +

Upload Image

+
+ + +
+ + ''' +frames = [] +@app.route('/upload', methods=['POST']) +def upload_file(): + if 'file' not in request.files: + return redirect(request.url) + + file = request.files['file'] + if file.filename == '': + return redirect(request.url) + + if file: + filepath = os.path.join(UPLOAD_FOLDER, file.filename) + file.save(filepath) + frames = resize_gif_and_get_colors(filepath, (128, 128)) + threading.Thread(target=start_websocket_thread, args=(frames,)).start() + # return send_file(resized_filepath, as_attachment=True) + return make_response('OK',200) + +def resize_gif_and_get_colors(input_path, new_size): + """ + Thay đổi kích thước từng khung hình của ảnh GIF và trả về mảng màu RGB565 cho từng khung hình. + + :param input_path: Đường dẫn đến ảnh GIF gốc + :param new_size: Kích thước mới (width, height) + :return: Danh sách các mảng màu của từng khung hình + """ + frames_colors = [] + + with Image.open(input_path) as img: + for frame in ImageSequence.Iterator(img): + frame = frame.convert('RGB').resize(new_size, Image.ANTIALIAS) + width, height = frame.size + frame_data = bytearray() + for y in range(height): + for x in range(width): + r, g, b = frame.getpixel((x, y)) + rgb565 = rgb888_to_rgb565(r, g, b) + frame_data.extend(struct.pack('!' + 'H', rgb565)) + + frames_colors.append((frame_data,width,height)) + + return frames_colors + +def rgb888_to_rgb565(r, g, b): + """Chuyển đổi từ RGB888 sang RGB565""" + return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3) +def load_image_to_rgb565(file_path): + """Tải tệp ảnh và chuyển đổi từng pixel sang định dạng RGB565""" + img = Image.open(file_path) + img = img.convert('RGB') # Đảm bảo ảnh ở định dạng RGB + + width, height = img.size + frame_data = [] + + for y in range(height): + for x in range(width): + r, g, b = img.getpixel((x, y)) + rgb565 = rgb888_to_rgb565(r, g, b) + frame_data.append(rgb565) + print(frame_data) + return frame_data +def load_gif_to_rgb565(file_path): + """Tải tệp GIF và chuyển đổi từng khung hình sang định dạng RGB565""" + gif = Image.open(file_path) + frames = [] + + for frame in ImageSequence.Iterator(gif): + frame = frame.convert('RGB') + width, height = frame.size + frame_data = [] + for y in range(height): + for x in range(width): + r, g, b = frame.getpixel((x, y)) + rgb565 = rgb888_to_rgb565(r, g, b) + frame_data.append(rgb565) + frames.append((frame_data, width, height)) + + return frames +def load_video_to_rgb565(file_path): + """Tải video và chuyển đổi từng khung hình sang định dạng RGB565""" + cap = cv2.VideoCapture(file_path) + frames = [] + + while True: + ret, frame = cap.read() + if not ret: + break + frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) + height, width = frame.shape[:2] + frame_data = [] + for y in range(height): + for x in range(width): + r, g, b = frame[y, x] + rgb565 = rgb888_to_rgb565(r, g, b) + frame_data.append(rgb565) + frames.append((frame_data, width, height)) + print(frames) + cap.release() + return frames +def send_frame(frame_data, udp_ip, udp_port): + """Gửi khung hình qua UDP""" + + packet_size = 1460 # Kích thước gói tối đa để tránh tràn UDP + num_packets = (len(frame_data) * 2 + packet_size - 1) // packet_size + for i in range(num_packets): + start_index = i * packet_size // 2 + end_index = min((i + 1) * packet_size // 2, len(frame_data)) + packet = struct.pack('!' + 'H' * (end_index - start_index), *frame_data[start_index:end_index]) + sock.sendto(packet, (udp_ip, udp_port)) + # time.sleep(0.1) + +def send_data_via_serial(port, baudrate, data): + with serial.Serial(port, baudrate, timeout=1) as ser: + # Gửi mảng dữ liệu + for value in data: + # Gửi giá trị RGB565 (2 byte) + ser.write(struct.pack(' bằng địa chỉ IP của ESP32 + # uri = "ws://localhost:8765" # Thay bằng địa chỉ IP của ESP32 + #frames = load_gif_to_rgb565(file_path) + async with websockets.connect(uri) as websocket: + while not stop_event.is_set(): + #frame_data = load_image_to_rgb565(file_path) + # frame_data = create_test_pattern() + for frame_data, _, _ in frames: + # Chia nhỏ dữ liệu nếu cần (tùy thuộc vào kích thước của dữ liệu và giới hạn của WebSocket) + chunk_size = 12288 # Kích thước mỗi phần dữ liệu + for i in range(0, len(frame_data), chunk_size): + chunk = frame_data[i:i + chunk_size] + await websocket.send(chunk) + await asyncio.sleep(1/10) # Giữ tốc độ gửi dữ liệu + +def main(): + app.run(debug=True) +if __name__ == "__main__": + main() + +``` + diff --git a/img/connector.jpg b/img/connector.jpg new file mode 100644 index 0000000000000000000000000000000000000000..880d134bd90c91bbbcada619a0b5f4275445917d GIT binary patch literal 31451 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 literal 0 HcmV?d00001