ArrcttacsrjksX commited on
Commit
b54b009
·
verified ·
1 Parent(s): 5bf065f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -88
app.py CHANGED
@@ -3,75 +3,78 @@ import subprocess
3
  import json
4
  import os
5
  import stat
 
 
6
  import zipfile
7
- from PIL import ImageFont
8
  import matplotlib.font_manager
 
9
 
10
- # Path to the compiled engine executable
 
 
 
11
  ENGINE_EXECUTABLE = "./engine"
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  def ensure_executable(file_path):
14
- """
15
- Đảm bảo rằng file có quyền thực thi.
16
- Nếu không, cấp quyền thực thi.
17
- """
18
- if not os.access(file_path, os.X_OK): # Kiểm tra quyền thực thi
19
- try:
20
- # Cấp quyền thực thi
21
- current_permissions = os.stat(file_path).st_mode
22
- os.chmod(file_path, current_permissions | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
23
- print(f"Granted execute permission to {file_path}")
24
- except Exception as e:
25
- raise PermissionError(f"Failed to grant execute permission to {file_path}: {e}")
26
 
27
- def extract_and_load_fonts_from_directory(directory="fontfile", extract_to="extracted_fonts"):
28
  if not os.path.exists(extract_to):
29
  os.makedirs(extract_to)
30
-
31
  fonts = []
32
-
33
- # Extract fonts from zip files
34
- for root, dirs, files in os.walk(directory):
35
  for file in files:
36
  if file.endswith(".zip"):
37
  zip_path = os.path.join(root, file)
38
  try:
39
  with zipfile.ZipFile(zip_path, 'r') as zip_ref:
40
  zip_ref.extractall(extract_to)
41
- print(f"Extracted: {zip_path}")
42
  except Exception as e:
43
  print(f"Failed to extract {zip_path}: {e}")
44
-
45
- # Collect all .ttf and .shx fonts
46
- for root, dirs, files in os.walk(extract_to):
47
  for file in files:
48
- if file.endswith(".ttf") or file.endswith(".shx"):
49
  fonts.append(os.path.join(root, file))
50
-
51
  return fonts
52
 
53
  def get_system_fonts():
54
- fonts = []
55
- for font in matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf'):
56
- fonts.append(font)
57
- return fonts
58
 
59
  def get_available_fonts():
60
- # Get system fonts
61
  system_fonts = get_system_fonts()
62
-
63
- # Extract and load custom fonts
64
- extracted_fonts = extract_and_load_fonts_from_directory()
65
-
66
- # Combine and deduplicate fonts
67
- all_fonts = list(set(system_fonts + extracted_fonts))
68
- return sorted(all_fonts)
69
-
70
- def call_engine(input_text, font_size, width, height, bg_color, text_color, mode, font_name, align, line_spacing, image_format):
71
- # Ensure the engine file is executable
 
 
 
 
 
 
72
  ensure_executable(ENGINE_EXECUTABLE)
73
-
74
- # Prepare input data as a dictionary
75
  input_data = {
76
  "input_text": input_text,
77
  "font_size": font_size,
@@ -80,76 +83,58 @@ def call_engine(input_text, font_size, width, height, bg_color, text_color, mode
80
  "bg_color": bg_color,
81
  "text_color": text_color,
82
  "mode": mode,
83
- "font_path": font_name, # Pass the selected font path
84
  "align": align,
85
  "line_spacing": line_spacing,
86
  "image_format": image_format
87
  }
88
-
89
- # Call the engine executable with input data
90
- result = subprocess.run(
91
- [ENGINE_EXECUTABLE, json.dumps(input_data)],
92
- capture_output=True,
93
- text=True
94
- )
95
-
96
- # Handle errors
97
  if result.returncode != 0:
98
- raise Exception(f"Engine failed with error: {result.stderr}")
99
-
100
- # Get the output image path from stdout
101
  output_path = result.stdout.strip()
 
 
 
102
 
103
- # Load the generated image
104
- if os.path.exists(output_path):
105
- return output_path
106
- else:
107
- raise Exception("Failed to generate image!")
 
108
 
109
  with gr.Blocks() as demo:
110
  gr.Markdown("# 🖼️ Text to Image Converter")
111
-
 
 
112
  with gr.Row():
113
  input_text = gr.Textbox(label="Enter Text", placeholder="Type or paste text here...", lines=5)
114
- file_input = gr.File(label="Upload a Text File", type="filepath")
115
-
116
  with gr.Row():
117
- font_size = gr.Slider(10, 100, value=30, label="Font Size")
118
-
119
- # Lấy danh sách font và đặt font mặc định là font đầu tiên
120
- available_fonts = get_available_fonts()
121
- default_font = available_fonts[0] if available_fonts else ""
122
-
123
  font_name = gr.Dropdown(choices=available_fonts, value=default_font, label="Font")
124
  align = gr.Radio(["Left", "Center", "Right"], label="Text Alignment", value="Center")
125
-
126
- with gr.Row():
127
- width = gr.Slider(200, 2000, value=800, label="Image Width")
128
- height = gr.Slider(200, 2000, value=600, label="Base Height")
129
-
130
  with gr.Row():
131
  bg_color = gr.ColorPicker(label="Background Color", value="#FFFFFF")
132
  text_color = gr.ColorPicker(label="Text Color", value="#000000")
133
-
134
  with gr.Row():
135
  mode = gr.Radio(["Plain Text", "LaTeX Math"], label="Rendering Mode", value="Plain Text")
136
  image_format = gr.Radio(["PNG", "JPEG"], label="Image Format", value="PNG")
137
-
138
- # Add line spacing slider
139
- line_spacing = gr.Slider(1.0, 3.0, value=1.2, step=0.1, label="Line Spacing")
140
-
141
  output_image = gr.Image(label="Generated Image")
142
-
143
- with gr.Row():
144
- convert_button = gr.Button("Convert Text to Image")
145
- file_convert_button = gr.Button("Convert File to Image")
146
-
147
  convert_button.click(
148
  call_engine,
149
- inputs=[
150
- input_text, font_size, width, height, bg_color, text_color,
151
- mode, font_name, align, line_spacing, image_format
152
- ],
153
  outputs=output_image
154
  )
155
 
 
3
  import json
4
  import os
5
  import stat
6
+ import requests
7
+ import datetime
8
  import zipfile
 
9
  import matplotlib.font_manager
10
+ from huggingface_hub import HfApi, HfFolder
11
 
12
+ # Hugging Face repo and token
13
+ HF_REPO = "ArrcttacsrjksX/Texttoimage"
14
+ HF_ENGINE_URL = "https://huggingface.co/ArrcttacsrjksX/Texttoimage/resolve/main/engine"
15
+ HF_TOKEN = os.getenv("HF_TOKEN") # Lấy token từ biến môi trường
16
  ENGINE_EXECUTABLE = "./engine"
17
 
18
+ def download_engine():
19
+ """Download engine from Hugging Face if not available."""
20
+ if not os.path.exists(ENGINE_EXECUTABLE):
21
+ headers = {"Authorization": f"Bearer {HF_TOKEN}"}
22
+ response = requests.get(HF_ENGINE_URL, headers=headers, stream=True)
23
+ if response.status_code == 200:
24
+ with open(ENGINE_EXECUTABLE, "wb") as f:
25
+ for chunk in response.iter_content(chunk_size=8192):
26
+ f.write(chunk)
27
+ os.chmod(ENGINE_EXECUTABLE, os.stat(ENGINE_EXECUTABLE).st_mode | stat.S_IXUSR)
28
+ else:
29
+ raise Exception("Failed to download engine")
30
+
31
  def ensure_executable(file_path):
32
+ if not os.access(file_path, os.X_OK):
33
+ os.chmod(file_path, os.stat(file_path).st_mode | stat.S_IXUSR)
 
 
 
 
 
 
 
 
 
 
34
 
35
+ def extract_and_load_fonts(directory="fontfile", extract_to="extracted_fonts"):
36
  if not os.path.exists(extract_to):
37
  os.makedirs(extract_to)
 
38
  fonts = []
39
+ for root, _, files in os.walk(directory):
 
 
40
  for file in files:
41
  if file.endswith(".zip"):
42
  zip_path = os.path.join(root, file)
43
  try:
44
  with zipfile.ZipFile(zip_path, 'r') as zip_ref:
45
  zip_ref.extractall(extract_to)
 
46
  except Exception as e:
47
  print(f"Failed to extract {zip_path}: {e}")
48
+ for root, _, files in os.walk(extract_to):
 
 
49
  for file in files:
50
+ if file.endswith(".ttf") or file.endswith(".otf") or file.endswith(".shx"):
51
  fonts.append(os.path.join(root, file))
 
52
  return fonts
53
 
54
  def get_system_fonts():
55
+ return matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf')
 
 
 
56
 
57
  def get_available_fonts():
 
58
  system_fonts = get_system_fonts()
59
+ extracted_fonts = extract_and_load_fonts()
60
+ return sorted(set(system_fonts + extracted_fonts))
61
+
62
+ def upload_to_huggingface(file_path, text_content, timestamp_folder):
63
+ """Upload image and text to Hugging Face repo."""
64
+ api = HfApi()
65
+ HfFolder.save_token(HF_TOKEN)
66
+ repo_path = f"{HF_REPO}/{timestamp_folder}"
67
+ api.upload_file(path_or_fileobj=file_path, path_in_repo=f"{repo_path}/image.png", repo_id=HF_REPO)
68
+ with open("temp_text.txt", "w") as f:
69
+ f.write(text_content)
70
+ api.upload_file(path_or_fileobj="temp_text.txt", path_in_repo=f"{repo_path}/text.txt", repo_id=HF_REPO)
71
+ os.remove("temp_text.txt")
72
+
73
+ def call_engine(file_input, input_text, font_size, width, height, bg_color, text_color, mode, font_name, align, line_spacing, image_format):
74
+ download_engine()
75
  ensure_executable(ENGINE_EXECUTABLE)
76
+ if file_input:
77
+ input_text = read_file_content(file_input)
78
  input_data = {
79
  "input_text": input_text,
80
  "font_size": font_size,
 
83
  "bg_color": bg_color,
84
  "text_color": text_color,
85
  "mode": mode,
86
+ "font_path": font_name,
87
  "align": align,
88
  "line_spacing": line_spacing,
89
  "image_format": image_format
90
  }
91
+ result = subprocess.run([ENGINE_EXECUTABLE, json.dumps(input_data)], capture_output=True, text=True)
 
 
 
 
 
 
 
 
92
  if result.returncode != 0:
93
+ raise Exception(f"Engine error: {result.stderr}")
 
 
94
  output_path = result.stdout.strip()
95
+ timestamp_folder = datetime.datetime.now().strftime("%d-%m-%Y %H-%M-%S")
96
+ upload_to_huggingface(output_path, input_text, timestamp_folder)
97
+ return output_path
98
 
99
+ def read_file_content(file):
100
+ """Read text from uploaded file."""
101
+ try:
102
+ return file.decode("utf-8") if isinstance(file, bytes) else file.read().decode("utf-8")
103
+ except Exception as e:
104
+ return f"Error reading file: {e}"
105
 
106
  with gr.Blocks() as demo:
107
  gr.Markdown("# 🖼️ Text to Image Converter")
108
+ available_fonts = get_available_fonts()
109
+ default_font = available_fonts[0] if available_fonts else ""
110
+
111
  with gr.Row():
112
  input_text = gr.Textbox(label="Enter Text", placeholder="Type or paste text here...", lines=5)
113
+ file_input = gr.File(label="Upload a Text File", type="binary")
114
+
115
  with gr.Row():
116
+ font_size = gr.Slider(0, 100, value=30, label="Font Size")
 
 
 
 
 
117
  font_name = gr.Dropdown(choices=available_fonts, value=default_font, label="Font")
118
  align = gr.Radio(["Left", "Center", "Right"], label="Text Alignment", value="Center")
119
+ width = gr.Slider(0, 2000, value=800, label="Image Width")
120
+ height = gr.Slider(0, 2000, value=600, label="Image Height")
121
+
 
 
122
  with gr.Row():
123
  bg_color = gr.ColorPicker(label="Background Color", value="#FFFFFF")
124
  text_color = gr.ColorPicker(label="Text Color", value="#000000")
125
+
126
  with gr.Row():
127
  mode = gr.Radio(["Plain Text", "LaTeX Math"], label="Rendering Mode", value="Plain Text")
128
  image_format = gr.Radio(["PNG", "JPEG"], label="Image Format", value="PNG")
129
+
130
+ line_spacing = gr.Slider(1.0, 10.0, value=1.2, step=0.1, label="Line Spacing")
 
 
131
  output_image = gr.Image(label="Generated Image")
132
+
133
+ convert_button = gr.Button("Convert Text to Image")
134
+
 
 
135
  convert_button.click(
136
  call_engine,
137
+ inputs=[file_input, input_text, font_size, width, height, bg_color, text_color, mode, font_name, align, line_spacing, image_format],
 
 
 
138
  outputs=output_image
139
  )
140