Advertisement
Paullux

Untitled

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