ndurner commited on
Commit
517fe9b
·
1 Parent(s): 3033ee9

image handling improvements

Browse files
Files changed (1) hide show
  1. llm.py +30 -8
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 = max(1568 / long_edge, 0.9)
175
  else:
176
- scale_factor = max(math.sqrt(1600 / tokens), 0.9)
 
 
 
177
 
178
- new_width = int(img.width * scale_factor)
179
- new_height = int(img.height * scale_factor)
180
 
181
- img = img.resize((new_width, new_height), Image.LANCZOS)
182
 
183
- long_edge = max(new_width, new_height)
184
- tokens = calculate_tokens(new_width, new_height)
185
 
186
  # Try to save in original format first
187
  buffer = io.BytesIO()
188
- img.save(buffer, format="webp", quality=95)
 
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