broyang commited on
Commit
2d0e5bd
·
1 Parent(s): 7787a69

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -177
app.py CHANGED
@@ -1,154 +1,9 @@
1
  import cv2
 
2
  import numpy as np
3
- import math
4
- from PIL import Image, ImageDraw, ImageFont, ImageOps
5
  Image.MAX_IMAGE_PIXELS = None
6
  import gradio as gr
7
-
8
- def get_exif(image_path):
9
- try:
10
- with Image.open(image_path) as img:
11
- exif_data = img.getexif()
12
- # print(exif_data)
13
- if not exif_data:
14
- return None, None, None
15
- if "Local Coordinates (m)" in exif_data[34737]:
16
- return None, None, None
17
- pixel_scale = exif_data[33550] # Tag ID for PixelScale
18
- model_tie_point = exif_data[33922] # Tag ID for ModelTiePoint
19
- pixel_scale_x, pixel_scale_y, _ = pixel_scale
20
- _, _, _, _, latitude, _ = model_tie_point
21
- return pixel_scale_x, pixel_scale_y, latitude
22
- except Exception as e:
23
- print(f"Error extracting metadata: {e}")
24
- return None, None, None
25
-
26
- def pixel_size_in_feet(x_scale_degrees, latitude):
27
- meters_per_degree_lat = 111320 # Average meters per degree of latitude
28
- meters_per_degree_lon = meters_per_degree_lat * math.cos(math.radians(latitude))
29
- pixel_size_x_feet = x_scale_degrees * meters_per_degree_lon * 3.28084
30
- return pixel_size_x_feet
31
-
32
- def feet_per_inch(dpi, pixel_size_x_feet):
33
- # Calculate the number of pixels in 1 inch
34
- pixels_per_inch = dpi
35
- # Calculate the number of feet in 1 inch
36
- feet_per_inch = pixels_per_inch * pixel_size_x_feet
37
- return feet_per_inch
38
-
39
- def nearest_number(n):
40
- numbers = [1, 5, 10, 20, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]
41
- return min(numbers, key=lambda x: abs(x - n))
42
-
43
- def calculate_dpi(x_scale_degrees, latitude):
44
- pixel_size_x_feet = pixel_size_in_feet(x_scale_degrees, latitude)
45
- pixel_size_x_inches = pixel_size_x_feet / 12
46
- dpi = 1 / pixel_size_x_inches
47
-
48
- return dpi
49
-
50
- def add_white_space(img):
51
- _, height_px = img.size
52
- bottom_space = int(height_px * 0.2) # Calculate the size of the bottom space
53
- top_space = int(height_px * 0.1) # Calculate the size of the top space
54
- new_height_px = int(height_px + bottom_space + top_space)
55
- img = ImageOps.expand(img, border=(0, top_space, 0, bottom_space), fill='white')
56
- return img, new_height_px
57
-
58
- def add_white_space_right(img):
59
- width_px, height_px = img.size
60
- right_space = int(width_px * 0.3) # Calculate the size of the right space
61
- left_space = int(width_px * 0.1) # Calculate the size of the left space
62
- new_width_px = int(width_px + right_space)
63
- img = ImageOps.expand(img, border=(0, 0, right_space, 0), fill='white')
64
- return img
65
-
66
- def draw_scale_bar(right_img, exif_data, compass, line_img, paste_x_position, paste_y_position):
67
- pixel_scale_x = exif_data[0]
68
- pixel_scale_y = exif_data[1]
69
- latitude = exif_data[2]
70
- if pixel_scale_x is None or pixel_scale_y is None or latitude is None:
71
- return
72
- # Calculate pixel size in feet
73
- pixel_size_x = pixel_size_in_feet(pixel_scale_x, latitude)
74
- image_width_feet = round(line_img.width * pixel_size_x)
75
- scale_max = nearest_number(image_width_feet / 5)
76
- # Calculate scale bar dimensions
77
- scale_bar_width_px = int(line_img.width * (scale_max / image_width_feet))
78
- scale_bar_height_px = int(scale_bar_width_px * 0.08)
79
- # x_position = int(right_img.width * 0.90 - scale_bar_width_px) # Adjusted for 5% from the right
80
- x_position = paste_x_position
81
- y_position = int(right_img.height - (right_img.height - paste_y_position - scale_bar_height_px) * 2) # Adjusted for new height
82
- font_size = int(scale_bar_width_px * 0.1)
83
- # Draw scale bar
84
- draw = ImageDraw.Draw(right_img)
85
- try:
86
- font = ImageFont.truetype("DejaVuSans.ttf", font_size) #DejaVuSans.ttf, Arial.ttf
87
- print("loaded font")
88
- except IOError:
89
- font = ImageFont.load_default()
90
- print("default :()")
91
- section_width = scale_bar_width_px / 4
92
- section_x_position = x_position - 1 * section_width #base 0 incremental position
93
- text_position = (section_x_position + section_width - font_size / 4, y_position - font_size - 20)
94
- draw.text(text_position, "0", fill="black", font=font)
95
- for i in range(4): #other incremental positions
96
- section_x_position = x_position + i * section_width
97
- fill_color = "black" if i % 2 == 0 else "white"
98
- draw.rectangle([section_x_position, y_position, section_x_position + section_width, y_position + scale_bar_height_px], fill=fill_color)
99
- text = str(round(scale_max / 4 * (i + 1), 2))
100
- if text.endswith('.0'):
101
- text = text.rstrip('0').rstrip('.')
102
- if i == 3:
103
- text += " feet"
104
- text_position = (section_x_position + section_width - font_size / 4, y_position - font_size - 20)
105
- draw.text(text_position, text, fill="black", font=font)
106
-
107
- # Draw outline around scale bar
108
- outline_width = 3
109
- draw.line([(x_position, y_position), (x_position + scale_bar_width_px, y_position)], fill="black", width=outline_width)
110
- draw.line([(x_position, y_position), (x_position, y_position + scale_bar_height_px)], fill="black", width=outline_width)
111
- draw.line([(x_position + scale_bar_width_px, y_position), (x_position + scale_bar_width_px, y_position + scale_bar_height_px)], fill="black", width=outline_width)
112
- draw.line([(x_position, y_position + scale_bar_height_px), (x_position + scale_bar_width_px, y_position + scale_bar_height_px)], fill="black", width=outline_width)
113
-
114
- #feet per inch
115
- try:
116
- font = ImageFont.truetype("DejaVuSans.ttf", int(font_size * 1.3)) #DejaVuSans.ttf, Arial.ttf
117
- except IOError:
118
- font = ImageFont.load_default()
119
- dpi = calculate_dpi(pixel_scale_x, latitude)
120
- dpi = 96
121
- fpi = round(feet_per_inch(dpi, pixel_size_x), 2)
122
- feet_per_inch_text = '1" = ' + str(fpi) + ' feet'
123
- paste_y_position = int(right_img.height - (right_img.height - paste_y_position - scale_bar_height_px) * 3)
124
- text_position = (x_position, paste_y_position)
125
- # text_position = (x_position, y_position - font_size - 200)
126
- draw.text(text_position, feet_per_inch_text, fill='black', font=font)
127
-
128
- # # Add in a small compass
129
- compass = compass.convert("RGBA")
130
- new_compass_width = int(right_img.width * 0.05)
131
- compass_ratio = new_compass_width / compass.width
132
- new_compass_height = int(compass.height * compass_ratio)
133
- compass = compass.resize((new_compass_width, new_compass_height))
134
- # Paste the compass in the top right of the image with 5% margin
135
- paste_compass_x_position = int(right_img.width - (right_img.width + new_compass_width * 2 - paste_x_position) / 2)
136
- # paste_compass_x_position = int(right_img.width * 0.05)
137
- paste_compass_y_position = int(right_img.height * 0.05) # 5% margin on the top
138
- right_img.paste(compass, (paste_compass_x_position, paste_compass_y_position), compass)
139
- return right_img
140
-
141
- def watermark(right_img, sb_logo, line_img):
142
- sb_logo = sb_logo.convert("RGBA")
143
- new_logo_width = int(line_img.width * 0.2)
144
- logo_ratio = new_logo_width / sb_logo.width
145
- new_logo_height = int(sb_logo.height * logo_ratio)
146
- sb_logo = sb_logo.resize((new_logo_width, new_logo_height))
147
- # Calculate the position for the logo to be 5% from the right
148
- paste_x_position = int(right_img.width * 0.95 - new_logo_width)
149
- paste_y_position = int(right_img.height * 0.95 - new_logo_height)#new_height_px - new_logo_height - int(bottom_space / 4)
150
- right_img.paste(sb_logo, (paste_x_position, paste_y_position), sb_logo)
151
- return right_img, paste_x_position, paste_y_position
152
 
153
  def freemium_watermark(img, sb_logo):
154
  width_px, height_px = img.size
@@ -168,35 +23,33 @@ def freemium_watermark(img, sb_logo):
168
  # Save the image
169
  return img
170
 
171
- def create_line_drawing(input_path):
172
- with Image.open(input_path) as img:
173
- img_array = np.array(img)
174
- # Line processing
175
- blurred = cv2.GaussianBlur(img_array, (7, 7), 0)
176
- edges = cv2.Canny(blurred, 100, 180)
177
- structuring_element = cv2.getStructuringElement(cv2.MORPH_RECT, (4,3))
178
- dilated_edges = cv2.dilate(edges, structuring_element, iterations=1)
179
- line_drawing = 255 - dilated_edges
180
- line_img = Image.fromarray(line_drawing)
181
-
182
- right_img = add_white_space_right(line_img)
183
- right_img, paste_x_position, paste_y_position = watermark(right_img, sb_logo, line_img)
184
- exif_data = list(get_exif(input_path))
185
- if str(exif_data) != str([None, None, None]):
186
- print(str(exif_data))
187
- print("drawing scale bar")
188
- line_img = draw_scale_bar(right_img, exif_data, compass, line_img, paste_x_position, paste_y_position)
189
- line_img = freemium_watermark(line_img, sb_logo)
190
- return line_img
191
- else:
192
- line_img = freemium_watermark(line_img, sb_logo)
193
- return line_img
194
-
195
  sb_logo = Image.open("./SB_logo_horizontal.png")
196
- compass = Image.open("./compass.jpg")
197
 
198
- demo = gr.Interface(create_line_drawing,
199
- inputs=gr.File(type="filepath"),
200
- outputs="image",
201
- live=True)
202
- demo.queue(max_size=10).launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import cv2
2
+ import os
3
  import numpy as np
4
+ from PIL import Image
 
5
  Image.MAX_IMAGE_PIXELS = None
6
  import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
  def freemium_watermark(img, sb_logo):
9
  width_px, height_px = img.size
 
23
  # Save the image
24
  return img
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  sb_logo = Image.open("./SB_logo_horizontal.png")
 
27
 
28
+ examples = [
29
+ os.path.join(os.path.dirname(__file__), "trailer.jpg"),
30
+ os.path.join(os.path.dirname(__file__), "road.jpg"),
31
+ ]
32
+
33
+ with gr.Blocks() as demo:
34
+ with gr.Row():
35
+ with gr.Column():
36
+ input = gr.Image(type="filepath", label="Upload Image", sources=["upload"])
37
+ with gr.Column():
38
+ image = gr.Image(label="Sketch Drawing", show_share_button=False)
39
+ examples = gr.Examples(examples=["road.jpg", "trailer.jpg"], inputs=[input])
40
+ @gr.on(inputs=[input], outputs=[image], show_progress="minimal")
41
+ def sketch(input_path):
42
+ if input_path is None:
43
+ return None
44
+ with Image.open(input_path) as img:
45
+ img_array = np.array(img)
46
+ # Line processing
47
+ blurred = cv2.GaussianBlur(img_array, (7, 7), 0)
48
+ edges = cv2.Canny(blurred, 100, 180)
49
+ structuring_element = cv2.getStructuringElement(cv2.MORPH_RECT, (4,3))
50
+ dilated_edges = cv2.dilate(edges, structuring_element, iterations=1)
51
+ line_drawing = 255 - dilated_edges
52
+ line_img = Image.fromarray(line_drawing)
53
+ return freemium_watermark(line_img, sb_logo)
54
+
55
+ demo.launch()