ComfyUI+text_animate in app.py is running

This commit is contained in:
Qiong-Yue 2024-12-04 17:07:18 +00:00
parent 40ec215291
commit 71023fd2f3
373 changed files with 1020 additions and 149 deletions

0
test_prompt/__init__.py Normal file
View File

View File

@ -6,24 +6,28 @@ import uuid
import json
import urllib.request
import urllib.parse
import time
import requests
import numpy as np
from numpy.typing import NDArray
import random
import cv2
from concurrent.futures import ThreadPoolExecutor, wait
import sys
import os
import asyncio
from datetime import datetime
from text_animate.lib import TextAnimate, EmotionDistribution
from text_animate.char.radical import string2radical
# Add the parent directory to sys.path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
# 获取当前脚本文件所在的目录
# 使用絕對匯入
# 將 Cloud_Image 設定為根目錄
script_dir = os.path.dirname(os.path.abspath(__file__))
# 构建相对 ComfyUI 目录的路径
comfyui_dir = os.path.abspath(os.path.join(script_dir, '..'))
cloud_image_dir = os.path.abspath(os.path.join(script_dir, '..', '..')) # 獲取 Cloud_Image 資料夾的路徑
sys.path.append(cloud_image_dir) # 添加 Cloud_Image 到 sys.path
from ECCV2022_RIFE.InterpolatorInterface import InterpolatorInterface
from generate_prompt import generate_prompt
from generate_prompt import generate_prompt, generate_chinese_prompt, get_emotion, get_temperature
from temperature import draw_thermometer, overlay_images
server_address = "127.0.0.1:8188"
client_id = str(uuid.uuid4())
@ -67,48 +71,174 @@ def get_images(ws, prompt):
return output_images
# prompt = json.loads(prompt_text)
def main():
# 讀取最新兩張圖片
def get_latest_images(directory, count=2):
# 獲取資料夾中的所有文件,排除隱藏文件
files = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f)) and not f.startswith('.')]
if not files:
return [] # 如果沒有圖片,返回空列表
# 按照最後修改時間對文件排序
files.sort(key=lambda f: os.path.getmtime(os.path.join(directory, f)), reverse=True)
# 取得最新的兩張圖片的檔案名稱
latest_images = files[:count]
return latest_images # 返回最新圖片的檔案名稱列表
def validate_image(path):
try:
from PIL import Image
img = Image.open(path)
img.verify() # 檢查影像完整性
return True
except Exception as e:
print(f"Image validation failed for {path}: {e}")
return False
# 假設這是處理 ComfyUI 的函數
def process_comfyui():
with open("workflow_api.json") as workflow_api:
prompt = json.load(workflow_api)
print("workflow_api open")
ws = websocket.WebSocket()
ws.connect("ws://{}/ws?clientId={}".format(server_address, client_id))
print(" ws.connect")
interpolator = InterpolatorInterface() # Initialize image to video
temp = 300
while(1):
next = temp + 1
# 生prompt
prompt_text = generate_prompt()
# ComfyUI 製圖
prompt_text = generate_prompt()
print(prompt_text)
prompt["3"]["inputs"]["seed"] = random.randint(0,999999999999999)
prompt["6"]["inputs"]["text"] = prompt_text
queue_prompt(prompt)['prompt_id'] # 將提示加入隊列(假設這個函數已經實現)
print(prompt_text)
# 生圖
prompt["6"]["inputs"]["text"] = prompt_text # 更新 CLIPTextEncode 的文本提示
queue_prompt(prompt)['prompt_id'] # 将提示加入队列并获取 prompt_id
# 設定 output 資料夾的路徑
output_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'output'))
# 讀取最新的兩張圖片檔案名稱
latest_images = get_latest_images(output_dir)
# print(latest_images[0])
# 拼接字串
image_path0 = "/Cloud_Image/ComfyUI/output/" + latest_images[0]
image_path1 = "/Cloud_Image/ComfyUI/output/" + latest_images[1]
print(prompt_text)
# 當 latest_images 不是預期的情況時,指定預設圖片
if len(latest_images) < 2:
print("Latest images not found or not enough images. Using default images.")
image_path0 = "/Cloud_Image/ComfyUI/output/ComfyUI_00003_.png" # 預設圖片 1
image_path1 = "/Cloud_Image/ComfyUI/output/ComfyUI_00004_.png" # 預設圖片 2
else:
image_path0 = os.path.join(output_dir, latest_images[0])
image_path1 = os.path.join(output_dir, latest_images[1])
# 檢查指定的圖片是否存在
if not os.path.exists(image_path0) or not os.path.exists(image_path1):
raise FileNotFoundError(f"Image path(s) not found: {image_path0}, {image_path1}")
# temp_str = f"output/ComfyUI_00{str(temp)}_.png"
# next_str = f"output/ComfyUI_00{str(next)}_.png"
temp_str = os.path.join(comfyui_dir, f"output/ComfyUI_00{str(temp)}_.png")
next_str = os.path.join(comfyui_dir, f"output/ComfyUI_00{str(next)}_.png")
# print(temp_str)
# 確保圖片有效,並傳遞給 interpolator
if validate_image(image_path0) and validate_image(image_path1):
results = interpolator.generate(
imgs=(image_path0, image_path1),
exp=4
)
else:
raise ValueError("Invalid images provided to interpolator.generate")
# 如果有圖片,顯示或處理
if latest_images:
# image to video
results = interpolator.generate(
imgs = (temp_str, next_str),
imgs=(image_path0, image_path1),
exp=4,
# output_dir="interpolate_out"
# output_dir=os.path.join(comfyui_dir, "interpolate_out")
)
temp = next
return results
print("process_comfyUI完成")
def process_radical():
prompt_chinese = generate_chinese_prompt()
radicals = string2radical(prompt_chinese)
print("process_radical完成")
return radicals
def draw_temperature(frame):
temperature = get_temperature()
thermometer = draw_thermometer(temperature)
origin = frame.copy()
scale_factor = 1 / 3
new_height = int(origin.shape[0] * scale_factor)
new_width = int((new_height / thermometer.shape[0]) * thermometer.shape[1])
thermometer = cv2.resize(thermometer, (new_width, new_height))
x_offset = origin.shape[1] - thermometer.shape[1] - 10
y_offset = 10
combined_frame = overlay_images(origin, thermometer, x_offset, y_offset, alpha=0.7)
return combined_frame
# 設定儲存路徑
output_dir = '/Cloud_Image/ComfyUI/test_prompt/no_style'
def main():
global latest_full_frame
ta = TextAnimate()
with ThreadPoolExecutor(max_workers=4) as general_executor:
while True:
future_radicals = general_executor.submit(process_radical)
future_comfyui = general_executor.submit(process_comfyui)
radicals = future_radicals.result()
bgs = future_comfyui.result()
EmotionDis = get_emotion()
for i in range(9):
temp_frame = draw_temperature(bgs[i])
print(i,"temp_frame finish")
print(EmotionDis)
print(temp_frame.shape)
# Convert frame to BGRA
if len(temp_frame.shape) == 2:
# 灰階
temp_frame = np.repeat(temp_frame[..., None], 4, axis=-1)
temp_frame[..., 3] = 255
elif len(temp_frame.shape) == 3:
if len(temp_frame[0][0]) == 3:
# BGR to BGRA
temp_frame = np.concatenate(
(temp_frame, np.full((*temp_frame.shape[:2], 1), 255, dtype=np.uint8)),
axis=-1,
)
# 畫文字
img = ta.draw(temp_frame, EmotionDistribution(**EmotionDis), radicals)
img = cv2.cvtColor(img.result(), cv2.COLOR_BGRA2BGR)
# 根據當前時間生成檔名
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"{timestamp}.png"
# 完整的儲存路徑
output_path = os.path.join(output_dir, filename)
# 使用 OpenCV 將陣列儲存成圖片
cv2.imwrite(output_path, img)
print("Output results to: ")
print(results)
print()
if __name__ == "__main__":
main()

179
test_prompt/app2.py Normal file
View File

@ -0,0 +1,179 @@
#This is an example that uses the websockets api and the SaveImageWebsocket node to get images directly without
#them being saved to disk
import websocket #NOTE: websocket-client (https://github.com/websocket-client/websocket-client)
import uuid
import json
import urllib.request
import urllib.parse
import numpy as np
from numpy.typing import NDArray
import random
import cv2
from concurrent.futures import ThreadPoolExecutor, wait
import sys
import os
import asyncio
from datetime import datetime
# 將 Cloud_Image 設定為根目錄
script_dir = os.path.dirname(os.path.abspath(__file__))
cloud_image_dir = os.path.abspath(os.path.join(script_dir, '..', '..')) # 獲取 Cloud_Image 資料夾的路徑
sys.path.append(cloud_image_dir) # 添加 Cloud_Image 到 sys.path
# 使用絕對匯入
from ECCV2022_RIFE.InterpolatorInterface import InterpolatorInterface
from generate_prompt2 import generate_prompt, get_emotion, get_temperature
from temperature import draw_thermometer, overlay_images
# 設定儲存路徑
output_dir = '/Cloud_Image/ComfyUI/test_prompt/test_image'
server_address = "127.0.0.1:8188"
client_id = str(uuid.uuid4())
def queue_prompt(prompt):
p = {"prompt": prompt, "client_id": client_id}
data = json.dumps(p).encode('utf-8')
req = urllib.request.Request("http://{}/prompt".format(server_address), data=data)
return json.loads(urllib.request.urlopen(req).read())
def get_image(filename, subfolder, folder_type):
data = {"filename": filename, "subfolder": subfolder, "type": folder_type}
url_values = urllib.parse.urlencode(data)
with urllib.request.urlopen("http://{}/view?{}".format(server_address, url_values)) as response:
return response.read()
def get_history(prompt_id):
with urllib.request.urlopen("http://{}/history/{}".format(server_address, prompt_id)) as response:
return json.loads(response.read())
def get_images(ws, prompt):
prompt_id = queue_prompt(prompt)['prompt_id']
output_images = {}
current_node = ""
while True:
out = ws.recv()
if isinstance(out, str):
message = json.loads(out)
if message['type'] == 'executing':
data = message['data']
if data['prompt_id'] == prompt_id:
if data['node'] is None:
break #Execution is done
else:
current_node = data['node']
else:
if current_node == 'save_image_websocket_node':
images_output = output_images.get(current_node, [])
images_output.append(out[8:])
output_images[current_node] = images_output
return output_images
# 讀取最新兩張圖片
def get_latest_images(directory, count=2):
# 獲取資料夾中的所有文件,排除隱藏文件
files = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f)) and not f.startswith('.')]
if not files:
return [] # 如果沒有圖片,返回空列表
# 按照最後修改時間對文件排序
files.sort(key=lambda f: os.path.getmtime(os.path.join(directory, f)), reverse=True)
# 取得最新的兩張圖片的檔案名稱
latest_images = files[:count]
return latest_images # 返回最新圖片的檔案名稱列表
# 假設這是處理 ComfyUI 的函數
def process_comfyui():
with open("workflow_api.json") as workflow_api:
prompt = json.load(workflow_api)
ws = websocket.WebSocket()
ws.connect("ws://{}/ws?clientId={}".format(server_address, client_id))
interpolator = InterpolatorInterface() # Initialize image to video
while True:
# ComfyUI 製圖
prompt_text = generate_prompt()
prompt["3"]["inputs"]["seed"] = random.randint(0,999999999999999)
prompt["6"]["inputs"]["text"] = prompt_text
queue_prompt(prompt)['prompt_id'] # 將提示加入隊列(假設這個函數已經實現)
print(prompt_text)
# 設定 output 資料夾的路徑
output_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'output'))
# 讀取最新的兩張圖片檔案名稱
latest_images = get_latest_images(output_dir)
# print(latest_images[0])
# 拼接字串
image_path0 = "/Cloud_Image/ComfyUI/output/" + latest_images[0]
image_path1 = "/Cloud_Image/ComfyUI/output/" + latest_images[1]
# 如果有圖片,顯示或處理
if latest_images:
# image to video
results = interpolator.generate(
imgs=(image_path0, image_path1),
exp=4,
# output_dir="interpolate_out"
# output_dir=os.path.join(comfyui_dir, "interpolate_out")
)
else:
print("No images found in the output directory.")
results = [np.zeros((100, 100, 3), dtype=np.uint8) for _ in range(9)]
print("process_comfyUI完成")
# print("Output results to: ")
# print(results)
# print()
return results
def draw_temperature(frame):
temperature = get_temperature()
thermometer = draw_thermometer(temperature)
origin = frame.copy()
scale_factor = 1 / 3
new_height = int(origin.shape[0] * scale_factor)
new_width = int((new_height / thermometer.shape[0]) * thermometer.shape[1])
thermometer = cv2.resize(thermometer, (new_width, new_height))
x_offset = origin.shape[1] - thermometer.shape[1] - 10
y_offset = 10
combined_frame = overlay_images(origin, thermometer, x_offset, y_offset, alpha=0.7)
return combined_frame
def main():
global latest_full_frame
while True:
result_frame = process_comfyui()
# 拿出 9 張照片添加溫不計
for i in range(9):
full_frame = draw_temperature(result_frame[i])
print("full_frame finish")
# print(type(full_frame))
# 根據當前時間生成檔名
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"{timestamp}.png"
# 完整的儲存路徑
output_path = os.path.join(output_dir, filename)
# 使用 OpenCV 將陣列儲存成圖片
cv2.imwrite(output_path, full_frame)
if __name__ == "__main__":
main()

120
test_prompt/data.txt Normal file
View File

@ -0,0 +1,120 @@
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 21 攝氏度, 積雨雲, 紅色, 春天早上,
{'angry': 1, 'disgust': 0, 'fear': 1, 'happy': 3, 'sad': 5, 'surprise': 0, 'neutral': 5}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 28 攝氏度, 積雲, 暗紅色, 夏天早上,
{'angry': 0, 'disgust': 0, 'fear': 1, 'happy': 2, 'sad': 1, 'surprise': 3, 'neutral': 1}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 24 攝氏度, 卷積雲, 亮綠色, 春天早上,
{'angry': 5, 'disgust': 3, 'fear': 1, 'happy': 0, 'sad': 5, 'surprise': 4, 'neutral': 5}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 28 攝氏度, 雨層雲, 黑色, 春天傍晚,
{'angry': 1, 'disgust': 5, 'fear': 4, 'happy': 2, 'sad': 5, 'surprise': 5, 'neutral': 4}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 27 攝氏度, 層雲, 深黃色, 夏天早上,
{'angry': 4, 'disgust': 1, 'fear': 2, 'happy': 0, 'sad': 4, 'surprise': 2, 'neutral': 3}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 20 攝氏度, 卷積雲, 亮綠色, 夏天傍晚,
{'angry': 2, 'disgust': 4, 'fear': 4, 'happy': 3, 'sad': 3, 'surprise': 5, 'neutral': 3}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 21 攝氏度, 積雨雲, 黑色, 夏天早上,
{'angry': 0, 'disgust': 1, 'fear': 1, 'happy': 0, 'sad': 2, 'surprise': 3, 'neutral': 4}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 30 攝氏度, 積雲, 紅色, 春天中午,
{'angry': 0, 'disgust': 1, 'fear': 1, 'happy': 4, 'sad': 5, 'surprise': 0, 'neutral': 2}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 37 攝氏度, 高層雲, 灰色, 冬天中午,
{'angry': 0, 'disgust': 5, 'fear': 4, 'happy': 1, 'sad': 2, 'surprise': 1, 'neutral': 1}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 37 攝氏度, 高層雲, 黑色, 冬天中午,
{'angry': 4, 'disgust': 3, 'fear': 5, 'happy': 3, 'sad': 3, 'surprise': 3, 'neutral': 0}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 31 攝氏度, 層雲, 深黃色, 冬天中午,
{'angry': 3, 'disgust': 1, 'fear': 0, 'happy': 3, 'sad': 2, 'surprise': 3, 'neutral': 3}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 36 攝氏度, 積雲, 暗紅色, 春天中午,
{'angry': 1, 'disgust': 4, 'fear': 5, 'happy': 4, 'sad': 2, 'surprise': 5, 'neutral': 3}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 40 攝氏度, 卷積雲, 亮綠色, 春天中午,
{'angry': 2, 'disgust': 4, 'fear': 4, 'happy': 2, 'sad': 3, 'surprise': 0, 'neutral': 0}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 33 攝氏度, 層積雲沒有顏色, 秋天中午,
{'angry': 5, 'disgust': 1, 'fear': 4, 'happy': 5, 'sad': 4, 'surprise': 0, 'neutral': 0}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 30 攝氏度, 積雨雲, 黑色, 秋天中午,
{'angry': 1, 'disgust': 1, 'fear': 1, 'happy': 1, 'sad': 4, 'surprise': 5, 'neutral': 5}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 37 攝氏度, 捲雲, 深黃色, 夏天中午,
{'angry': 4, 'disgust': 3, 'fear': 2, 'happy': 5, 'sad': 0, 'surprise': 4, 'neutral': 4}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 9 攝氏度, 卷積雲, 黃色, 秋天晚上,
{'angry': 3, 'disgust': 4, 'fear': 1, 'happy': 2, 'sad': 1, 'surprise': 4, 'neutral': 2}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 9 攝氏度, 層雲, 深黃色, 夏天晚上,
{'angry': 0, 'disgust': 3, 'fear': 2, 'happy': 2, 'sad': 5, 'surprise': 4, 'neutral': 5}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 9 攝氏度, 捲雲, 深黃色, 春天晚上,
{'angry': 1, 'disgust': 0, 'fear': 2, 'happy': 5, 'sad': 1, 'surprise': 5, 'neutral': 0}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 3 攝氏度, 積雲, 紅色, 秋天晚上,
{'angry': 2, 'disgust': 4, 'fear': 5, 'happy': 4, 'sad': 2, 'surprise': 3, 'neutral': 3}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 8 攝氏度, 高積雲, 亮粉色, 夏天晚上,
{'angry': 0, 'disgust': 5, 'fear': 3, 'happy': 3, 'sad': 0, 'surprise': 1, 'neutral': 0}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 4 攝氏度, 層積雲沒有顏色, 夏天晚上,
{'angry': 3, 'disgust': 5, 'fear': 3, 'happy': 3, 'sad': 0, 'surprise': 0, 'neutral': 5}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 10 攝氏度, 層雲, 棕色, 冬天傍晚,
{'angry': 5, 'disgust': 5, 'fear': 0, 'happy': 4, 'sad': 3, 'surprise': 1, 'neutral': 4}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 10 攝氏度, 層雲, 棕色, 冬天傍晚,
{'angry': 3, 'disgust': 1, 'fear': 1, 'happy': 2, 'sad': 2, 'surprise': 4, 'neutral': 5}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 19 攝氏度, 卷積雲, 深黃色, 冬天傍晚,
{'angry': 0, 'disgust': 1, 'fear': 3, 'happy': 3, 'sad': 1, 'surprise': 3, 'neutral': 4}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 12 攝氏度, 層雲, 棕色, 秋天早上,
{'angry': 2, 'disgust': 3, 'fear': 2, 'happy': 3, 'sad': 4, 'surprise': 0, 'neutral': 1}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 10 攝氏度, 卷積雲, 亮綠色, 冬天傍晚,
{'angry': 5, 'disgust': 3, 'fear': 1, 'happy': 0, 'sad': 4, 'surprise': 3, 'neutral': 2}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 16 攝氏度, 積雨雲, 黑色, 冬天傍晚,
{'angry': 0, 'disgust': 1, 'fear': 2, 'happy': 2, 'sad': 2, 'surprise': 1, 'neutral': 4}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 13 攝氏度, 積雨雲, 黑色, 冬天傍晚,
{'angry': 2, 'disgust': 4, 'fear': 1, 'happy': 5, 'sad': 0, 'surprise': 4, 'neutral': 5}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 13 攝氏度, 層積雲沒有顏色, 冬天早上,
{'angry': 3, 'disgust': 4, 'fear': 2, 'happy': 4, 'sad': 3, 'surprise': 4, 'neutral': 5}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 22 攝氏度, 積雨雲, 紅色, 夏天傍晚,
{'angry': 2, 'disgust': 0, 'fear': 3, 'happy': 1, 'sad': 0, 'surprise': 0, 'neutral': 0}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 29 攝氏度, 積雲, 紅色, 春天早上,
{'angry': 5, 'disgust': 1, 'fear': 3, 'happy': 3, 'sad': 4, 'surprise': 4, 'neutral': 5}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 29 攝氏度, 卷積雲, 亮綠色, 夏天傍晚,
{'angry': 5, 'disgust': 2, 'fear': 3, 'happy': 1, 'sad': 1, 'surprise': 5, 'neutral': 2}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 28 攝氏度, 層雲, 棕色, 夏天傍晚,
{'angry': 4, 'disgust': 3, 'fear': 0, 'happy': 0, 'sad': 0, 'surprise': 3, 'neutral': 1}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 20 攝氏度, 積雨雲, 黑色, 夏天傍晚,
{'angry': 1, 'disgust': 2, 'fear': 4, 'happy': 5, 'sad': 4, 'surprise': 5, 'neutral': 5}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 23 攝氏度, 層雲, 棕色, 夏天傍晚,
{'angry': 0, 'disgust': 1, 'fear': 1, 'happy': 1, 'sad': 5, 'surprise': 1, 'neutral': 2}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 30 攝氏度, 積雲, 暗紅色, 冬天中午,
{'angry': 1, 'disgust': 2, 'fear': 4, 'happy': 3, 'sad': 3, 'surprise': 0, 'neutral': 5}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 37 攝氏度, 積雲, 紅色, 春天中午,
{'angry': 1, 'disgust': 4, 'fear': 1, 'happy': 0, 'sad': 0, 'surprise': 4, 'neutral': 1}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 31 攝氏度, 積雲, 紅色, 秋天中午,
{'angry': 5, 'disgust': 2, 'fear': 1, 'happy': 0, 'sad': 1, 'surprise': 5, 'neutral': 3}
Loaded v3.x HD model.
天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, 30 攝氏度, 積雲, 紅色, 春天中午,
{'angry': 1, 'disgust': 3, 'fear': 5, 'happy': 1, 'sad': 4, 'surprise': 3, 'neutral': 5}

View File

@ -3,17 +3,28 @@ import requests
import time
import random
emotions: dict = {}
temperature_r = 0
count_t = 0
def fetch_data():
global count_t
# Function to continuously fetch temperature data
while True:
url = "http://140.119.108.248:89/ComfyUI_Data/"
response = requests.get(url)
data = response.json()
time.sleep(1) # Fetch temperature every 1 second
if data:
temperature = data['temperature']
emotions_vec = data['dominant_emotion']
yield temperature, emotions_vec
count_t = count_t+1
emotions_vec = tuple(random. choices (range (1, 6), k=7))
if count_t < 20:
temperature = random. randint (0,10)
elif count_t < 40:
temperature = random. randint (10,21)
elif count_t < 60:
temperature = random. randint (20,31)
elif count_t < 80:
temperature = random. randint (30,41)
else:
temperature = 0
count_t = 0
yield temperature, emotions_vec
def get_dominant_emotion(emotions_vec):
@ -123,7 +134,10 @@ def choose_date(temperature):
def generate_prompt():
global emotions, temperature_r
for temperature, emotions_vec in fetch_data():
emotions = tran_dict(emotions_vec)
temperature_r = temperature
# print(f"Temperature: {temperature}, Emotions: {emotions_vec}")
temperature_str = str(temperature) #str
dominant_emotion = get_dominant_emotion(emotions_vec)
@ -134,17 +148,23 @@ def generate_prompt():
prompt = "weather forecast, no people, only show the sky, fantasy style, " + temperature_str + " degrees Celsius, " + cloud_types + color + season + timing
print(prompt)
# print(prompt)
# weather forecast, no people, only show the sky, fantasy style, 33 degrees Celsius, cirrus, Bright green, spring noon,
return prompt
def generate_chinese_prompt():
def tran_dict(emotions_vec):
b = {}
for key, value in zip(["angry", "disgust", "fear", "happy", "sad", "surprise", "neutral"],emotions_vec):
b[key] = value
return b
def generate_chinese_prompt():
for temperature, emotions_vec in fetch_data():
# print(f"Temperature: {temperature}, Emotions: {emotions_vec}")
temperature_str = str(temperature) #str
dominant_emotion = get_dominant_emotion(emotions_vec)
cloud_types, color = choose_cloud_and_color_chinese(dominant_emotion) # str
season_num, timing_num = choose_date(temperature)
season = season_chinese[season_num] #str
@ -157,6 +177,11 @@ def generate_chinese_prompt():
# weather forecast, no people, only show the sky, fantasy style, 33 degrees Celsius, cirrus, Bright green, spring noon,
return prompt
def get_emotion():
return emotions
# if __name__ == "__main__":
# generate_prompt()
def get_temperature():
return temperature_r
if __name__ == "__main__":
print(generate_prompt())

View File

@ -0,0 +1,218 @@
# Input溫度, 情緒向量 < 4, 0, 0, 0, 1, 0, 0 >
import requests
import time
import random
import asyncio
import websockets
emotions: dict = {}
temperature_r = 0
count = 0
def get_dominant_emotion(emotions_vec):
# 找到最大值的索引
max_index = emotions_vec.index(max(emotions_vec))
# 用索引來查找對應的情緒
emotions = ["angry", "disgust", "fear", "happy", "sad", "surprise", "neutral"]
dominant_emotion = emotions[max_index]
return dominant_emotion
# cloud_types_and_color
def choose_cloud_and_color(dominant_emotion):
if(dominant_emotion == "angry"):
cloud_type = "cumulus, "
color = random.choice(["Red, ", "Dark red, "])
elif(dominant_emotion == "disgust"):
cloud_type = "stratus, "
color = random.choice(["Grown, ", "Dark yellow, "])
elif(dominant_emotion == "fear"):
cloud_type = "cumulonimbus, "
color = random.choice(["Red, ", "Black, "])
elif(dominant_emotion == "happy"):
cloud_type = random.choice(["cirrus, ", "cirrostratus, "])
color = random.choice(["Yellow, ", "Bright green, "])
elif(dominant_emotion == "sad"):
cloud_type = random.choice(["altostratus, ", "nimbostratus, "])
color = random.choice(["Gray, ", "Black, "])
elif(dominant_emotion == "surprise"):
cloud_type = random.choice(["cirroscumulus, ", "altocumulus, "])
color = random.choice(["Yellow, ", "Bright Green, ", "Bright Pink, "])
else:
cloud_type = "stratocumulus"
color = "No color, "
return cloud_type, color
# cloud_types_and_color
def choose_cloud_and_color_chinese(dominant_emotion):
if(dominant_emotion == "angry"):
cloud_type = "積雲, "
color = random.choice(["紅色, ", "暗紅色, "])
elif(dominant_emotion == "disgust"):
cloud_type = "層雲, "
color = random.choice(["棕色, ", "深黃色, "])
elif(dominant_emotion == "fear"):
cloud_type = "積雨雲, "
color = random.choice(["紅色, ", "黑色, "])
elif(dominant_emotion == "happy"):
cloud_type = random.choice(["捲雲, ", "卷積雲, "])
color = random.choice(["深黃色, ", "亮綠色, "])
elif(dominant_emotion == "sad"):
cloud_type = random.choice(["高層雲, ", "雨層雲, "])
color = random.choice(["灰色, ", "黑色, "])
elif(dominant_emotion == "surprise"):
cloud_type = random.choice(["卷積雲, ", "高積雲, "])
color = random.choice(["黃色, ", "亮綠色, ", "亮粉色, "])
else:
cloud_type = "層積雲"
color = "沒有顏色, "
return cloud_type, color
# timing
season_list = ['spring ', 'summer ', 'fall ', 'winter ', 'unknown ']
timing_list = ['morning, ', 'evening, ','noon, ', 'night, ', 'unknown, ' ]
season_chinese = ['春天', '夏天', '秋天', '冬天', '季節皆可']
timing_chinese = ['早上, ', '傍晚, ', '中午, ', '晚上, ', '時間皆可, ']
def choose_date(temperature):
season_num = 0
timing_num = 0
if 0 <= temperature < 10:
season_num = random.randint(0, 3)
timing_num = 3
elif 10 <= temperature < 20:
season_num = random.randint(2, 3)
timing_num = random.randint(0, 1)
elif 20 <= temperature < 30:
season_num = random.randint(0, 1)
timing_num = random.randint(0, 1)
elif 30 <= temperature <= 40:
season_num = random.randint(0, 3)
timing_num = 2
else:
season_num = 4
timing_num = 4
return season_num, timing_num
def generate_prompt():
global emotions, temperature_r
for temperature, emotions_vec in fetch_data():
emotions = tran_dict(emotions_vec)
temperature_r = temperature
# print(f"Temperature: {temperature}, Emotions: {emotions_vec}")
temperature_str = str(temperature) #str
dominant_emotion = get_dominant_emotion(emotions_vec)
cloud_types, color = choose_cloud_and_color(dominant_emotion) # str
season_num, timing_num = choose_date(temperature)
season = season_list[season_num] #str
timing = timing_list[timing_num] #str
prompt = "weather forecast, no people, only show the sky, fantasy style, " + temperature_str + " degrees Celsius, " + cloud_types + color + season + timing
# print(prompt)
# weather forecast, no people, only show the sky, fantasy style, 33 degrees Celsius, cirrus, Bright green, spring noon,
return prompt
def tran_dict(emotions_vec):
b = {}
for key, value in zip(["angry", "disgust", "fear", "happy", "sad", "surprise", "neutral"],emotions_vec):
b[key] = value
return b
def generate_chinese_prompt():
for temperature, emotions_vec in fetch_data():
# print(f"Temperature: {temperature}, Emotions: {emotions_vec}")
temperature_str = str(temperature) #str
dominant_emotion = get_dominant_emotion(emotions_vec)
cloud_types, color = choose_cloud_and_color_chinese(dominant_emotion) # str
season_num, timing_num = choose_date(temperature)
season = season_chinese[season_num] #str
timing = timing_chinese[timing_num] #str
prompt = "天氣預報, 沒有人物, 只顯示雲層, 奇幻風格, " + temperature_str + " 攝氏度, " + cloud_types + color + season + timing
print(prompt)
# weather forecast, no people, only show the sky, fantasy style, 33 degrees Celsius, cirrus, Bright green, spring noon,
return prompt
def get_emotion():
return emotions
def get_temperature():
return temperature_r
def fetch_data():
temperature = random_temp()
emotions_vec = random_emotions()
yield temperature, emotions_vec
def random_emotions():
global count
while count >= -1:
count = count + 1
if count < 15:
dominant_emotions = [random.randint(0, 5) for _ in range(7)]
elif count < 30:
dominant_emotions = [random.randint(0, 5) for _ in range(7)]
elif count < 45:
dominant_emotions = [random.randint(0, 5) for _ in range(7)]
elif count < 60:
dominant_emotions = [random.randint(0, 5) for _ in range(7)]
else:
count = 1
dominant_emotions = [random.randint(0, 5) for _ in range(7)]
return dominant_emotions
def random_temp():
global count
while count >= -1:
count = count + 1
if count < 15:
temperature = random.randint(0, 10)
elif count < 30:
temperature = random.randint(10, 20)
elif count < 45:
temperature = random.randint(20, 30)
elif count < 60:
temperature = random.randint(30, 40)
else:
count = 1
temperature = random.randint(30, 40)
return temperature
if __name__ == "__main__":
print(generate_prompt())

View File

@ -0,0 +1,64 @@
import cv2
import numpy as np
import requests
import time
# Function to draw the fixed parts of the thermometer (outline and labels)
def draw_fixed_parts(img):
# Draw the outline of the thermometer
outline = np.array([[250, 50], [275, 50], [275, 460], [225, 460], [225, 50], [250, 50]], np.int32)
cv2.polylines(img, [outline], isClosed=True, color=(0, 0, 0), thickness=5)
# Add temperature labels
cv2.putText(img, '0', (180, 450), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0), 2, cv2.LINE_AA)
cv2.putText(img, '40', (180, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0), 2, cv2.LINE_AA)
# Draw the bulb
cv2.circle(img, (250, 460), 50, (0, 0, 0), 5)
# Function to update the filled bulb color
def fill_bulb(img, color):
cv2.circle(img, (250, 460), 50, color, -1)
# Function to update the temperature bar and color
def update_temperature_bar(img, temp, color):
top = int(460 - 410 * temp / 40)
bar = np.array([[250, 460], [270, 460], [270, top], [230, top], [230, 460], [250, 460]], np.int32)
cv2.fillPoly(img, [bar], color)
cv2.putText(img, f'{temp:.1f}', (330, top + 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0), 2, cv2.LINE_AA)
# Function to create the thermometer image
def draw_thermometer(temperature):
img = np.ones((600, 600, 3), dtype=np.uint8) * 255
draw_fixed_parts(img)
# color_map = [(1, (255, 191, 0)), (11, (173, 255, 47)), (21, (255, 165, 0)), (31, (255, 0, 0)), (40, (255, 0, 0))]
color_map = [(11, (255, 255, 0)), (21, (144, 238, 144)), (31, (0, 127, 255)), (40, (0, 0, 255))]
color = (0, 0, 255)
for start_temp, start_color in color_map:
if temperature <= start_temp:
color = start_color
break
update_temperature_bar(img, temperature, color)
fill_bulb(img, color)
return img
# Function to overlay images with transparency
def overlay_images(background, overlay, x_offset, y_offset, alpha=0.5):
y1, y2 = y_offset, y_offset + overlay.shape[0]
x1, x2 = x_offset, x_offset + overlay.shape[1]
# Ensure the overlay fits within the background
if y2 > background.shape[0]:
y2 = background.shape[0]
overlay = overlay[:y2 - y1, :]
if x2 > background.shape[1]:
x2 = background.shape[1]
overlay = overlay[:, :x2 - x1]
# Blend images
background[y1:y2, x1:x2] = cv2.addWeighted(background[y1:y2, x1:x2], 1 - alpha, overlay, alpha, 0)
return background

View File

@ -99,3 +99,119 @@ def main():
if __name__ == "__main__":
main()
####################### 沒有文字藝術的串接
#This is an example that uses the websockets api and the SaveImageWebsocket node to get images directly without
#them being saved to disk
import websocket #NOTE: websocket-client (https://github.com/websocket-client/websocket-client)
import uuid
import json
import urllib.request
import urllib.parse
import time
import requests
import random
import sys
import os
# Add the parent directory to sys.path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
# 获取当前脚本文件所在的目录
script_dir = os.path.dirname(os.path.abspath(__file__))
# 构建相对 ComfyUI 目录的路径
comfyui_dir = os.path.abspath(os.path.join(script_dir, '..'))
from ECCV2022_RIFE.InterpolatorInterface import InterpolatorInterface
from generate_prompt import generate_prompt
server_address = "127.0.0.1:8188"
client_id = str(uuid.uuid4())
def queue_prompt(prompt):
p = {"prompt": prompt, "client_id": client_id}
data = json.dumps(p).encode('utf-8')
req = urllib.request.Request("http://{}/prompt".format(server_address), data=data)
return json.loads(urllib.request.urlopen(req).read())
def get_image(filename, subfolder, folder_type):
data = {"filename": filename, "subfolder": subfolder, "type": folder_type}
url_values = urllib.parse.urlencode(data)
with urllib.request.urlopen("http://{}/view?{}".format(server_address, url_values)) as response:
return response.read()
def get_history(prompt_id):
with urllib.request.urlopen("http://{}/history/{}".format(server_address, prompt_id)) as response:
return json.loads(response.read())
def get_images(ws, prompt):
prompt_id = queue_prompt(prompt)['prompt_id']
output_images = {}
current_node = ""
while True:
out = ws.recv()
if isinstance(out, str):
message = json.loads(out)
if message['type'] == 'executing':
data = message['data']
if data['prompt_id'] == prompt_id:
if data['node'] is None:
break #Execution is done
else:
current_node = data['node']
else:
if current_node == 'save_image_websocket_node':
images_output = output_images.get(current_node, [])
images_output.append(out[8:])
output_images[current_node] = images_output
return output_images
# prompt = json.loads(prompt_text)
def main():
with open("workflow_api.json") as workflow_api:
prompt = json.load(workflow_api)
ws = websocket.WebSocket()
ws.connect("ws://{}/ws?clientId={}".format(server_address, client_id))
interpolator = InterpolatorInterface() # Initialize image to video
temp = 300
while(1):
next = temp + 1
# 生prompt
prompt_text = generate_prompt()
# 生圖
prompt["6"]["inputs"]["text"] = prompt_text # 更新 CLIPTextEncode 的文本提示
queue_prompt(prompt)['prompt_id'] # 将提示加入队列并获取 prompt_id
print(prompt_text)
# temp_str = f"output/ComfyUI_00{str(temp)}_.png"
# next_str = f"output/ComfyUI_00{str(next)}_.png"
temp_str = os.path.join(comfyui_dir, f"output/ComfyUI_00{str(temp)}_.png")
next_str = os.path.join(comfyui_dir, f"output/ComfyUI_00{str(next)}_.png")
# print(temp_str)
# image to video
results = interpolator.generate(
imgs = (temp_str, next_str),
exp=4,
# output_dir="interpolate_out"
# output_dir=os.path.join(comfyui_dir, "interpolate_out")
)
temp = next
print("Output results to: ")
print(results)
print()
if __name__ == "__main__":
main()

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Some files were not shown because too many files have changed in this diff Show More