Spaces:
Sleeping
Sleeping
image handling improvements
Browse files
llm.py
CHANGED
@@ -153,6 +153,22 @@ class LLM:
|
|
153 |
except IOError:
|
154 |
raise Exception("Unknown image type")
|
155 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
# check if within the limits for Claude as per https://docs.anthropic.com/en/docs/build-with-claude/vision
|
157 |
def calculate_tokens(width, height):
|
158 |
return (width * height) / 750
|
@@ -169,23 +185,29 @@ class LLM:
|
|
169 |
}
|
170 |
|
171 |
# If we need to modify the image, proceed with resizing and/or compression
|
|
|
|
|
172 |
while long_edge > 1568 or tokens > 1600:
|
173 |
if long_edge > 1568:
|
174 |
-
scale_factor =
|
175 |
else:
|
176 |
-
scale_factor =
|
|
|
|
|
|
|
177 |
|
178 |
-
new_width = int(
|
179 |
-
new_height = int(
|
180 |
|
181 |
-
img =
|
182 |
|
183 |
-
long_edge = max(
|
184 |
-
tokens = calculate_tokens(
|
185 |
|
186 |
# Try to save in original format first
|
187 |
buffer = io.BytesIO()
|
188 |
-
|
|
|
189 |
image_data = buffer.getvalue()
|
190 |
|
191 |
# If the image is still too large, switch to WebP and compress
|
|
|
153 |
except IOError:
|
154 |
raise Exception("Unknown image type")
|
155 |
|
156 |
+
# Ensure correct orientation based on EXIF
|
157 |
+
try:
|
158 |
+
exif = img._getexif()
|
159 |
+
if exif:
|
160 |
+
orientation = exif.get(274) # 274 is the orientation tag
|
161 |
+
if orientation:
|
162 |
+
# Rotate or flip based on EXIF orientation
|
163 |
+
if orientation == 3:
|
164 |
+
img = img.rotate(180, expand=True)
|
165 |
+
elif orientation == 6:
|
166 |
+
img = img.rotate(270, expand=True)
|
167 |
+
elif orientation == 8:
|
168 |
+
img = img.rotate(90, expand=True)
|
169 |
+
except:
|
170 |
+
pass # If EXIF processing fails, use image as-is
|
171 |
+
|
172 |
# check if within the limits for Claude as per https://docs.anthropic.com/en/docs/build-with-claude/vision
|
173 |
def calculate_tokens(width, height):
|
174 |
return (width * height) / 750
|
|
|
185 |
}
|
186 |
|
187 |
# If we need to modify the image, proceed with resizing and/or compression
|
188 |
+
orig_scale_factor = 1
|
189 |
+
orig_img = img
|
190 |
while long_edge > 1568 or tokens > 1600:
|
191 |
if long_edge > 1568:
|
192 |
+
scale_factor = min(1568 / long_edge, 0.9)
|
193 |
else:
|
194 |
+
scale_factor = min(math.sqrt(1600 / tokens), 0.9)
|
195 |
+
|
196 |
+
scale_factor = orig_scale_factor * scale_factor
|
197 |
+
orig_scale_factor = scale_factor
|
198 |
|
199 |
+
new_width = int(orig_img.width * scale_factor)
|
200 |
+
new_height = int(orig_img.height * scale_factor)
|
201 |
|
202 |
+
img = orig_img.resize((new_width, new_height), Image.LANCZOS)
|
203 |
|
204 |
+
long_edge = max(img.width, img.height)
|
205 |
+
tokens = calculate_tokens(img.width, img.height)
|
206 |
|
207 |
# Try to save in original format first
|
208 |
buffer = io.BytesIO()
|
209 |
+
out_fmt = "png" if original_format == "png" else "webp"
|
210 |
+
img.save(buffer, format=out_fmt, quality=95 if out_fmt == "webp" else None)
|
211 |
image_data = buffer.getvalue()
|
212 |
|
213 |
# If the image is still too large, switch to WebP and compress
|