Paullux

Untitled

Jun 20th, 2023
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.23 KB | None | 0 0
  1. import os
  2. import platform
  3. import queue
  4. import random
  5. import sys
  6. import time
  7. import cv2
  8. import re
  9. import numpy as np
  10. import pyvirtualcam
  11. import threading
  12. from PIL import Image, ImageDraw, ImageFont
  13. from PyQt6.QtCore import Qt, QObject, pyqtSignal, QTimer
  14. from PyQt6.QtGui import QCloseEvent, QIcon, QImage, QKeyEvent, QPixmap, QColor, QPainter, QFont, QFontDatabase
  15. from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget, QComboBox, QPushButton
  16.  
  17. class Communicator(QObject):
  18. update_image_label_signal = pyqtSignal(QImage)
  19. def __init__(self, parent=None):
  20. super().__init__(parent)
  21.  
  22.  
  23. class CameraApp(QMainWindow):
  24. cameraSelected = pyqtSignal(int)
  25. def __init__(self, matrix):
  26. self.matrix = matrix
  27. super().__init__()
  28. self.init_ui()
  29.  
  30. if getattr(sys, 'frozen', False):
  31. import pyi_splash
  32.  
  33. # Fermeture du splash screen
  34. pyi_splash.update_text('UI Loaded ...')
  35. pyi_splash.close()
  36.  
  37. print("entre dans la init de CameraApp")
  38. self.cap = None
  39. self.timer = QTimer()
  40.  
  41. def init_ui(self):
  42. print("entre dans init_ui()")
  43. self.setWindowTitle("CameraSelector")
  44. self.setWindowFlags(self.windowFlags() & ~Qt.WindowType.FramelessWindowHint)
  45. self.wd = sys._MEIPASS if getattr(sys, 'frozen', False) else ''
  46. self.setWindowIcon(QIcon(os.path.join(self.wd, "icon-32.png")))
  47. self.layout = QVBoxLayout()
  48. self.central_widget = QWidget()
  49. self.camera_selector = QComboBox()
  50. self.camera_selector.addItem("Caméra non choisie")
  51. self.populate_camera_selector()
  52.  
  53. self.label = QLabel("Sélectionnez une caméra pour commencer")
  54.  
  55. # Créez le bouton et connectez-le à la méthode open_matrix_window
  56. self.open_matrix_button = QPushButton("Ouvrir Matrix")
  57. self.open_matrix_button.clicked.connect(self.camera_chosen)
  58.  
  59. # Ajoutez le bouton à votre interface utilisateur
  60. self.layout.addWidget(self.camera_selector)
  61. self.layout.addWidget(self.label)
  62. self.layout.addWidget(self.open_matrix_button)
  63. self.central_widget.setLayout(self.layout)
  64. self.setCentralWidget(self.central_widget)
  65.  
  66.  
  67. def camera_chosen(self):
  68. index = self.camera_selector.currentIndex()
  69. if index == 0:
  70. self.label.setText("Veuillez choisir une caméra.") # Utilise setText pour mettre à jour le texte du QLabel
  71. return
  72. if self.cap is not None:
  73. self.cap.release()
  74. camera_names, camera_indices = self.get_available_cameras()
  75. camera_name = camera_names[index - 1]
  76. index = camera_indices[index - 1]
  77. self.label.setText(f"Matrix Launched with {camera_name}") # Utilise setText pour mettre à jour le texte du QLabel
  78. self.cameraSelected.emit(index) # Émettre le signal avec l'index de la caméra sélectionnée
  79. self.matrix.show() # Affichage de la fenêtre Matrix
  80. self.close()
  81. print("Matrix Launched")
  82.  
  83. def populate_camera_selector(self):
  84. print("entre dans populate_camera_selector()")
  85. camera_names, camera_indices = self.get_available_cameras()
  86. for name, index in zip(camera_names, camera_indices):
  87. self.camera_selector.addItem(f"{name} (Index: {index})", index)
  88. pass
  89.  
  90. def get_available_cameras(self):
  91. print("entre dans get_available_cameras()")
  92. if sys.platform.startswith("linux"):
  93. camera_names, camera_indices = self.get_cameras_linux()
  94. elif sys.platform.startswith("win32"):
  95. camera_names, camera_indices = self.get_cameras_windows()
  96. elif sys.platform.startswith("darwin"): #macOS
  97. camera_names, camera_indices = self.get_cameras_mac()
  98. else:
  99. print("Plateforme non prise en charge")
  100. camera_names, camera_indices = [], []
  101.  
  102. return camera_names, camera_indices
  103.  
  104.  
  105. def get_cameras_mac(self):
  106. print("entre dans get_cameras_mac()")
  107. try:
  108. import Quartz
  109. except ImportError:
  110. print("Installez pyobjc avec 'pip install pyobjc'")
  111. return {}
  112.  
  113. camera_indices = []
  114. camera_names = []
  115.  
  116. for index, device in enumerate(Quartz.IORegistryIteratorCreateForMatchingService(Quartz.kIOMasterPortDefault, Quartz.CFDictionaryCreate(None, (Quartz.kIOUSBDeviceClassName,), (True,), 1))):
  117. camera_name = Quartz.IORegistryEntryGetName(device)
  118. if "infrared" in camera_name.lower() or "ir" in camera_name.lower():
  119. continue # Ignore the infrared camera
  120. camera_names.append(camera_name)
  121. camera_indices.append(index)
  122. return camera_names, camera_indices
  123.  
  124. def get_cameras_windows(self):
  125. print("entre dans get_cameras_windows()")
  126. try:
  127. from pygrabber.dshow_graph import FilterGraph
  128.  
  129. except ImportError:
  130. print("Installez pygrabber avec 'pip install pygrabber'")
  131. return {}
  132.  
  133. camera_indices = []
  134. camera_names = []
  135.  
  136. # Get a list of all connected HID devices
  137. devices = FilterGraph().get_input_devices()
  138.  
  139. camera_names, camera_indices = [], []
  140.  
  141. for device_index, device_name in enumerate(devices):
  142. camera_names.append(device_name)
  143. camera_indices.append(device_index)
  144.  
  145. return camera_names, camera_indices
  146.  
  147.  
  148. def get_cameras_linux(self):
  149. try:
  150. from v4l2py import Device
  151. except ImportError:
  152. print("Installez v4l2py avec 'pip install v4l2py'")
  153. return {}
  154.  
  155. devices = []
  156. camera_names = []
  157. camera_indices = []
  158. index = 0
  159.  
  160. while True:
  161. try:
  162. cap = cv2.VideoCapture(index)
  163. if cap.isOpened():
  164. devices.append(index)
  165. cap.release()
  166. else:
  167. print(f"Avertissement: Impossible d'ouvrir la caméra {index}")
  168. time.sleep(0.1)
  169. index += 1
  170. if index > 9:
  171. break
  172. except Exception as e:
  173. print(f"Erreur lors de l'ouverture des caméras: {e}")
  174. break
  175.  
  176. for index in devices:
  177. print(f"Récupération des informations de la caméra {index}")
  178. try:
  179. with Device.from_id(index) as cam:
  180. cam.open()
  181. camera_name = cam.info.card
  182. if camera_name not in camera_names:
  183. camera_names.append(camera_name)
  184. camera_indices.append(index)
  185. cam.close()
  186. except Exception as e:
  187. print(f"Erreur lors de l'accès à la caméra {index}: {e}")
  188.  
  189. return camera_names, camera_indices
  190.  
  191.  
  192. def closeEvent(self, event):
  193. print("entre dans closeEvent()")
  194. if self.timer.isActive():
  195. self.timer.stop()
  196.  
  197. class Matrix(QMainWindow):
  198. def __init__(self):
  199. super().__init__()
  200. self.threads = []
  201. self.wd = sys._MEIPASS if getattr(sys, 'frozen', False) else ''
  202.  
  203. self.running = True
  204.  
  205. self.font_path = os.path.join(self.wd, '.', 'mtx.ttf')
  206.  
  207. # Créez une file d'attente pour chaque variable partagée
  208. global columns_launched_queue, frame_queue, ascii_image_result_queue, rain_ascii_image_queue, drop_of_water_image_ascii_queue, virtual_frame_queue, running
  209. columns_launched_queue = queue.Queue()
  210. frame_queue = queue.Queue()
  211. ascii_image_result_queue = queue.Queue()
  212. rain_ascii_image_queue = queue.Queue()
  213. drop_of_water_image_ascii_queue = queue.Queue()
  214. virtual_frame_queue = queue.Queue()
  215. self.queues = [columns_launched_queue, frame_queue, ascii_image_result_queue, rain_ascii_image_queue, drop_of_water_image_ascii_queue, virtual_frame_queue]
  216.  
  217. running = True
  218.  
  219. self.communicator = Communicator()
  220. self.communicator.update_image_label_signal.connect(self.update_image_label)
  221.  
  222. if sys.platform == 'win32':
  223. import ctypes
  224. winVer = platform.win32_ver(release='')[0]
  225. try:
  226. if int(winVer) >= 10:
  227. ctypes.windll.shcore.SetProcessDpiAwareness(2)
  228. elif int(winVer) == 8:
  229. ctypes.windll.shcore.SetProcessDpiAwareness(1)
  230. else:
  231. ctypes.windll.user32.SetProcessDPIAware()
  232. except (ImportError, AttributeError, OSError):
  233. pass
  234.  
  235. self.counter = 0
  236. self.timer = QTimer(self)
  237. self.image_label = QLabel()
  238. self.timer.timeout.connect(self.update_counter)
  239. self.timer.start(1000)
  240.  
  241. # Définition des caractères à utiliser pour l'ASCII art
  242. #characters = ' ú.ù,:öøýü×Öų·ÈØÙÍб´¶¹º¼Â²ÇËÒÓ¾Ú'
  243.  
  244. self.rain_intensity = 0.5
  245. self.image_updated = ""
  246.  
  247. width, height = 854, 480
  248.  
  249. self.ascii_font_size_width = 20
  250. self.ascii_font_size_height = self.ascii_font_size_width * 9 / 16
  251.  
  252. self.font_path = os.path.join(self.wd, 'mtx.ttf')
  253. self.canvas_image = Image.new('RGB', (width, height), 'black')
  254. self.draw = ImageDraw.Draw(self.canvas_image)
  255. self.font = ImageFont.truetype(self.font_path, self.ascii_font_size_width)
  256.  
  257. # Variables partagées entre les threads
  258. self.ascii_image = ""
  259. ascii_image_result, rain_ascii_image, rain_ascii_image_result, drop_of_water_image_ascii = "", "","", ""
  260. # initialisation des ascii art
  261. for line in range(0, 106):
  262. for column in range(0, 106):
  263. ascii_image_result += ' '
  264. rain_ascii_image += ' '
  265. rain_ascii_image_result += ' '
  266. drop_of_water_image_ascii += ' '
  267. ascii_image_result += '\n'
  268. rain_ascii_image += '\n'
  269. rain_ascii_image_result += '\n'
  270. drop_of_water_image_ascii += '\n'
  271.  
  272. def update_counter(self):
  273. print("entre dans update_counter()\n")
  274. self.counter += 1
  275. self.counter_string = str(self.counter)
  276.  
  277. if random.randint(0, 9) % 2 == 0:
  278. self.counter_string = self.counter_string.replace("0", "¦")
  279. if random.randint(0, 9) % 2 == 0:
  280. self.counter_string = self.counter_string.replace("1","§")
  281. if random.randint(0, 9) % 2 == 0:
  282. self.counter_string = self.counter_string.replace("2", "¨")
  283. if random.randint(0, 9) % 2 == 0:
  284. self.counter_string = self.counter_string.replace("3", "©")
  285. if random.randint(0, 9) % 2 == 0:
  286. self.counter_string = self.counter_string.replace("4", "ª")
  287. if random.randint(0, 9) % 2 == 0:
  288. self.counter_string = self.counter_string.replace("5", "«")
  289. if random.randint(0, 9) % 2 == 0:
  290. self.counter_string = self.counter_string.replace("6", "¬")
  291. if random.randint(0, 9) % 2 == 0:
  292. self.counter_string = self.counter_string.replace("8", "®")
  293. if random.randint(0, 9) % 2 == 0:
  294. self.counter_string = self.counter_string.replace("9", "¯")
  295.  
  296.  
  297. pixmap = QPixmap(854, 480) # Créez un QPixmap de la taille souhaitée
  298. pixmap.fill(QColor(0,0,0)) # Remplissez-le avec une couleur transparente
  299.  
  300. painter = QPainter(pixmap)
  301.  
  302. font_id = QFontDatabase.addApplicationFont(self.font_path)
  303. if font_id < 0: print("Error")
  304. families = QFontDatabase.applicationFontFamilies(font_id)
  305. painter.setFont(QFont(families[0], 40))
  306. painter.setPen(QColor("#008800"))
  307.  
  308. self.counter_txt = "C O M P T E U R : "
  309.  
  310. if random.randint(0, 9) % 2 == 0:
  311. self.counter_txt = self.counter_txt.replace("C", "Ý")
  312. if random.randint(0, 9) % 2 == 0:
  313. self.counter_txt = self.counter_txt.replace("M", "ç")
  314. if random.randint(0, 9) % 2 == 0:
  315. self.counter_txt = self.counter_txt.replace("P", "ê")
  316. if random.randint(0, 9) % 2 == 0:
  317. self.counter_txt = self.counter_txt.replace("T", "î")
  318. if random.randint(0, 9) % 2 == 0:
  319. self.counter_txt = self.counter_txt.replace("E", "ß")
  320. if random.randint(0, 9) % 2 == 0:
  321. self.counter_txt = self.counter_txt.replace("U", "ï")
  322. if random.randint(0, 9) % 2 == 0:
  323. self.counter_txt = self.counter_txt.replace("R", "ì")
  324.  
  325.  
  326. print(self.counter_txt + self.counter_string)
  327.  
  328. painter.drawText(pixmap.rect(), Qt.AlignmentFlag.AlignCenter, self.counter_txt + self.counter_string)
  329.  
  330. painter.end()
  331. if random.randint(0, 9) % 3 == 0:
  332. self.image_label.setPixmap(pixmap)
  333.  
  334. def launch_threads(self):
  335. print("entre dans launch_multithread()\n")
  336. self.methods = [
  337. self.capture_frame,
  338. self.update_ascii_image,
  339. self.create_rain_drops,
  340. self.send_to_virtual_camera,
  341. self.create_virtual_camera
  342. ]
  343.  
  344. # Lancement des threads
  345. count = 1
  346. for method in self.methods:
  347. thread = threading.Thread(target=method)
  348. thread.start()
  349. print(f"{method.__name__} dans le thread {count}\n")
  350. self.threads.append(thread)
  351. count += 1
  352.  
  353. self.initUI()
  354.  
  355.  
  356. def setCameraIndex(self, index):
  357. global cap
  358. print("entre dans setCameraIndex()\n")
  359. print(f"Caméra sélectionnée : {index}")
  360. self.camera_index = index
  361. print(f"Setting camera with index {self.camera_index}")
  362.  
  363. # Create a new instance of cv2.VideoCapture with the selected camera index
  364. # Open the camera
  365. if platform.system() == 'Windows':
  366. self.cap = cv2.VideoCapture(self.camera_index, cv2.CAP_DSHOW)
  367. else:
  368. self.cap = cv2.VideoCapture(self.camera_index)
  369.  
  370. self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 854)
  371. self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
  372. self.capture_fps = 30
  373. cap = self.cap
  374.  
  375. def stop(self):
  376. print("entre dans stop()\n")
  377. global running
  378. running = False
  379. for queue in self.queues:
  380. for _ in range(3):
  381. queue.put(None)
  382. queue.queue.clear()
  383. #print("Toutes les Files d'Attentes ont étées vidées\n")
  384. for thread in self.threads:
  385. thread.join(timeout=.25)
  386. time.sleep(.251)
  387. #print("Tous les Multiples Threads ont étés arrêtées\n")
  388. sys.exit(0)
  389.  
  390. def update_image_label(self, qimage):
  391. self.image_label.setPixmap(QPixmap.fromImage(qimage))
  392.  
  393. def initUI(self):
  394. print("entre dans initUI()\n")
  395. self.setWindowFlags(self.windowFlags() & ~Qt.WindowType.FramelessWindowHint)
  396.  
  397. # Appliquez le layout au widget central
  398. self.window_icon = QIcon(os.path.join(self.wd, "icon-32.png"))
  399. self.setWindowIcon(self.window_icon)
  400. self.setWindowTitle("Matrix")
  401. self.setGeometry(300, 300, 854, 480)
  402.  
  403. # Créez une instance de QWidget
  404. self.central_widget = QWidget()
  405. # Définissez le widget central
  406. self.setCentralWidget(self.central_widget)
  407.  
  408.  
  409. # Utilisez le QWidget central comme parent pour le QVBoxLayout
  410. self.layout = QVBoxLayout(self.central_widget)
  411.  
  412. # Instanciez QLabel et assignez-le à self.image_label
  413. self.image_label = QLabel()
  414.  
  415. # Créez une QPixmap vide de taille 854x480
  416. pixmap = QPixmap(854, 480)
  417. pixmap.fill(QColor(0, 0, 0))
  418.  
  419. # Attribuez la QPixmap au QLabel
  420. self.image_label.setPixmap(pixmap)
  421.  
  422. # Ajoutez le QLabel image_label au layout
  423. self.layout.addWidget(self.image_label)
  424.  
  425. # self.setLayout(self.layout)
  426.  
  427. #self.launch_multithread()
  428. self.show()
  429. self.camera_app = CameraApp(self)
  430. self.camera_app.close()
  431.  
  432. def closeEvent(self, event: QCloseEvent):
  433. global running
  434. print("entre dans closeEvent()\n")
  435. running = False
  436. for queue in self.queues:
  437. for _ in range(3):
  438. queue.put(None)
  439. queue.queue.clear()
  440. #print("Toutes les Files d'Attentes ont étées vidées\n")
  441. for thread in self.threads:
  442. thread.join(timeout=.25)
  443. time.sleep(.251)
  444. #print("Tous les Multiples Threads ont étés arrêtées\n")
  445. sys.exit(0)
  446.  
  447. def keyPressEvent(self, event: QKeyEvent):
  448. global running
  449. print("entre dans keyPressEvent()\n")
  450. if event.key() == Qt.Key.Key_Escape:
  451. running = False
  452. self.stop()
  453. self.closeEvent()
  454. else:
  455. super(Matrix, self).keyPressEvent(event)
  456.  
  457. # Fonction pour convertir une intensité en caractère ASCII
  458. def get_character(self, intensity):
  459. characters = ' ú.ù,:öøýü×Öų·ÈØÙÍб´¶¹º¼Â²ÇËÒÓ¾Ú'
  460. num_levels = len(characters)
  461. level = intensity * (num_levels - 1) // 255
  462. return characters[level]
  463.  
  464. # Fonction pour convertir une image en ASCII artq
  465. def image_to_ascii(self, image):
  466. ascii_font_size_width = 8
  467. ascii_font_size_height = ascii_font_size_width * 9 / 16
  468. ratio = 1.725
  469. try:
  470. if len(image.shape) > 2 and image.shape[2] == 3:
  471. gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  472. else:
  473. gray_image = image
  474. resized_image = cv2.resize(gray_image, (int(gray_image.shape[1] / (ratio * ascii_font_size_height)), int(gray_image.shape[0] / (ratio * ascii_font_size_width))))
  475. ascii_image = ""
  476. for i in range(resized_image.shape[0]):
  477. for j in range(resized_image.shape[1]):
  478. intensity = resized_image[i][j]
  479. ascii_image += self.get_character(intensity)
  480. ascii_image += "\n"
  481. return ascii_image
  482. except Exception as e:
  483. print(f"Erreur dans image_to_ascii: {e}")
  484.  
  485. # créer l'effets de pluie
  486. def create_rain_drops(self):
  487. global rain_ascii_image_queue, drop_of_water_image_ascii_queue, running
  488. print("on rentre dans rain_drops()")
  489. drop_positions = np.zeros(854, dtype=int)
  490. drop_of_water_image = np.zeros((480, 854), dtype=np.uint8)
  491. blank_image = np.zeros((480, 854), dtype=np.uint8)
  492. drop_columns = []
  493. try:
  494. while running:
  495. if len(drop_columns) < 80:
  496. column = random.randint(0, blank_image.shape[1] - 1)
  497. drop_columns.append(column)
  498. drop_positions[column] = 0
  499. for column in drop_columns:
  500. row = drop_positions[column]
  501. if row >= blank_image.shape[0] - 1:
  502. drop_columns.remove(column)
  503. for row_to_erase in range(0, row):
  504. if row_to_erase < 480:
  505. blank_image[row_to_erase][column] = 0
  506. else:
  507. row += 1
  508. drop_positions[column] = row
  509. for row_line in range(0, row):
  510. blank_image[row_line][column] = 255
  511. row_drop = row + 2
  512. if row_drop < 480:
  513. for row_erase in range(0, row_drop):
  514. drop_of_water_image[row_erase][column] = 0
  515. for row_create in range(row_drop-2, row_drop + 5):
  516. if row_create < 480:
  517. drop_of_water_image[row_create][column] = 255
  518.  
  519. rain_ascii_image = self.image_to_ascii(blank_image)
  520. drop_of_water_image_ascii = self.image_to_ascii(drop_of_water_image)
  521.  
  522. drop_of_water_image_ascii_queue.put(drop_of_water_image_ascii)
  523. rain_ascii_image_queue.put(rain_ascii_image)
  524.  
  525. except Exception as e:
  526. print(f"Erreur dans create_rain_drops: {e}")
  527.  
  528. # Fonction pour mettre à jour l'image capturée
  529. def capture_frame(self):
  530. global frame_queue, cap, running
  531. capture = cap
  532. print("entre dans capture_frame()\n" + str(running))
  533. wd = sys._MEIPASS if getattr(sys, 'frozen', False) else ''
  534. width, height = 854, 480
  535. logo = cv2.imread(os.path.join(wd, 'MatrixLogo.png'))
  536. size1, size2 = 854, 150
  537. logo = cv2.resize(logo, (size1, size2))
  538. message = True
  539. get_camera = False
  540. while running:
  541. try:
  542. if not (cap is None) and not get_camera:
  543. capture = cap
  544. print(f"Dans capture_frame: La camera est définit")
  545. get_camera = True
  546. ret, frame = capture.read()
  547. f = frame
  548. if ret:
  549. # Redimensionner l'image capturée pour qu'elle s'adapte aux dimensions du canevas
  550. resized_frame = cv2.resize(f, (width, height))
  551. # Créer un canevas vide
  552. canvas = np.zeros((height, width, 3), dtype=np.uint8)
  553. # Calculer les coordonnées pour placer le logo au centre du canevas
  554. logo_x = int((width - size1) / 2)
  555. logo_y = 0
  556. # Dessiner le logo sur le canevas
  557. canvas[logo_y:logo_y+size2, logo_x:logo_x+size1] = logo
  558. # Combiner le canevas avec l'image capturée redimensionnée
  559. combined_frame = cv2.addWeighted(resized_frame, .5, canvas, 1, 0)
  560.  
  561. frame = combined_frame
  562. frame_queue.put(frame)
  563.  
  564. except Exception as e:
  565. if message:
  566. print(f"Erreur dans capture_frame: {e}")
  567. message = False
  568.  
  569. # Fonction pour mettre à jour l'image ASCII
  570. def update_ascii_image(self):
  571. global frame_queue, ascii_image_result_queue, running
  572. frame = None
  573. try:
  574. print("entre dans update_ascii_image()\n" + str(running))
  575. while running:
  576. if not frame_queue.empty():
  577. while not frame_queue.empty():
  578. frame = frame_queue.get()
  579. else:
  580. pass
  581. f = frame
  582. if f is not None:
  583. y_image = self.image_to_ascii(f)
  584. ascii_image_result = y_image
  585. ascii_image_result_queue.put(ascii_image_result)
  586. time.sleep(0.001)
  587. except Exception as e:
  588. print(f"Erreur dans update_ascii_image: {e}")
  589.  
  590. def send_to_virtual_camera(self):
  591. global ascii_image_result_queue, rain_ascii_image_queue, drop_of_water_image_ascii_queue, virtual_frame_queue, running
  592. width, height = 854, 480
  593. ascii_font_size_width = 16
  594. wd = sys._MEIPASS if getattr(sys, 'frozen', False) else ''
  595. font_path = os.path.join(wd, '.', 'mtx.ttf')
  596.  
  597. # Initialisez les variables avec des valeurs par défaut
  598. ascii_image_result = ""
  599. rain_ascii_image = ""
  600. drop_of_water_image_ascii = ""
  601.  
  602. try:
  603. print("entre dans send_to_virtual_camera()\n" + str(running))
  604. while running:
  605. if not ascii_image_result_queue.empty():
  606. while not ascii_image_result_queue.empty():
  607. ascii_image_result = ascii_image_result_queue.get()
  608. else:
  609. pass
  610.  
  611. if not drop_of_water_image_ascii_queue.empty():
  612. drop_of_water_image_ascii = drop_of_water_image_ascii_queue.get()
  613. else:
  614. pass
  615.  
  616. if not rain_ascii_image_queue.empty():
  617. rain_ascii_image = rain_ascii_image_queue.get()
  618. else:
  619. pass
  620.  
  621. canvas_image = Image.new('RGB', (width, height), 'black')
  622. draw = ImageDraw.Draw(canvas_image)
  623. font = ImageFont.truetype(font_path, ascii_font_size_width)
  624. draw.text((0, 0), ascii_image_result, fill='#006600', font=font)
  625. draw.text((0, 0), rain_ascii_image, fill='#00ff00', font=font)
  626. draw.text((0, 0), drop_of_water_image_ascii, fill='white', font=font)
  627. virtual_frame = cv2.cvtColor(np.array(canvas_image), cv2.COLOR_RGB2BGR)
  628.  
  629. rgb_image = cv2.cvtColor(virtual_frame, cv2.COLOR_BGR2RGB)
  630. h, w, ch = rgb_image.shape
  631. bytes_per_line = ch * w
  632. qimage = QImage(rgb_image.data, w, h, bytes_per_line, QImage.Format.Format_RGB888)
  633.  
  634. self.communicator = Communicator()
  635. self.communicator.update_image_label_signal.emit(qimage)
  636.  
  637. virtual_frame = virtual_frame
  638. virtual_frame_queue.put(virtual_frame)
  639.  
  640. except Exception as e:
  641. print(f"Erreur dans send_to_virtual_camera: {e}")
  642.  
  643. def create_virtual_camera(self):
  644. global virtual_frame_queue, running
  645. print("entre dans create_virtual_camera()\n")
  646. virtual_frame = np.zeros((480, 854, 3), dtype=np.uint8)
  647. old_virtual_frame = virtual_frame
  648. while running:
  649. try:
  650. if sys.platform.startswith("linux"):
  651. with pyvirtualcam.Camera(width=854, height=480, fps=30, device='/dev/video4') as cam:
  652. if not virtual_frame_queue.empty():
  653. while not virtual_frame_queue.empty():
  654. virtual_frame = virtual_frame_queue.get()
  655. cam.send(virtual_frame)
  656. cam.sleep_until_next_frame()
  657. else:
  658. virtual_frame = old_virtual_frame
  659. cam.send(virtual_frame)
  660. cam.sleep_until_next_frame()
  661. # raise ValueError("virtual_frame n'est pas encore disponible")
  662. else:
  663. with pyvirtualcam.Camera(854, 480, 30) as cam:
  664. if not virtual_frame_queue.empty():
  665. while not virtual_frame_queue.empty():
  666. virtual_frame = virtual_frame_queue.get()
  667. cam.send(virtual_frame)
  668. cam.sleep_until_next_frame()
  669. else:
  670. virtual_frame = old_virtual_frame
  671. cam.send(virtual_frame)
  672. cam.sleep_until_next_frame()
  673. #raise ValueError("virtual_frame n'est pas encore disponible")
  674. old_virtual_frame = virtual_frame
  675. except Exception as e:
  676. print(f"Erreur dans create_virtual_camera: {e}")
  677. pass
  678.  
  679. if __name__ == "__main__":
  680. app = QApplication([])
  681. matrix = Matrix()
  682. camera_app = CameraApp(matrix)
  683. communicator = Communicator()
  684. camera_app.cameraSelected.connect(matrix.setCameraIndex)
  685. communicator.update_image_label_signal.connect(matrix.update_image_label)
  686. camera_app.show()
  687. matrix.launch_threads() # Appel de la méthode de lancement des threads
  688. app.exec()
Advertisement
Add Comment
Please, Sign In to add comment