Ensure thumbnail be smaller than 64K (#3722)
Browse files### What problem does this PR solve?
Ensure thumbnail be smaller than 64K. Close #1443
### Type of change
- [x] Bug Fix (non-breaking change which fixes an issue)
---------
Co-authored-by: Kevin Hu <[email protected]>
- api/utils/file_utils.py +30 -7
api/utils/file_utils.py
CHANGED
@@ -170,29 +170,52 @@ def filename_type(filename):
|
|
170 |
return FileType.OTHER.value
|
171 |
|
172 |
def thumbnail_img(filename, blob):
|
|
|
|
|
|
|
173 |
filename = filename.lower()
|
174 |
if re.match(r".*\.pdf$", filename):
|
175 |
pdf = pdfplumber.open(BytesIO(blob))
|
176 |
buffered = BytesIO()
|
177 |
-
|
178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
|
180 |
-
|
181 |
image = Image.open(BytesIO(blob))
|
182 |
image.thumbnail((30, 30))
|
183 |
buffered = BytesIO()
|
184 |
image.save(buffered, format="png")
|
185 |
return buffered.getvalue()
|
186 |
|
187 |
-
|
188 |
import aspose.slides as slides
|
189 |
import aspose.pydrawing as drawing
|
190 |
try:
|
191 |
with slides.Presentation(BytesIO(blob)) as presentation:
|
192 |
buffered = BytesIO()
|
193 |
-
|
194 |
-
|
195 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
except Exception:
|
197 |
pass
|
198 |
return None
|
|
|
170 |
return FileType.OTHER.value
|
171 |
|
172 |
def thumbnail_img(filename, blob):
|
173 |
+
"""
|
174 |
+
MySQL LongText max length is 65535
|
175 |
+
"""
|
176 |
filename = filename.lower()
|
177 |
if re.match(r".*\.pdf$", filename):
|
178 |
pdf = pdfplumber.open(BytesIO(blob))
|
179 |
buffered = BytesIO()
|
180 |
+
resolution = 32
|
181 |
+
img = None
|
182 |
+
for _ in range(10):
|
183 |
+
# https://github.com/jsvine/pdfplumber?tab=readme-ov-file#creating-a-pageimage-with-to_image
|
184 |
+
pdf.pages[0].to_image(resolution=resolution).annotated.save(buffered, format="png")
|
185 |
+
img = buffered.getvalue()
|
186 |
+
if len(img) >= 64000 and resolution >= 2:
|
187 |
+
resolution = resolution / 2
|
188 |
+
buffered = BytesIO()
|
189 |
+
else:
|
190 |
+
break
|
191 |
+
return img
|
192 |
|
193 |
+
elif re.match(r".*\.(jpg|jpeg|png|tif|gif|icon|ico|webp)$", filename):
|
194 |
image = Image.open(BytesIO(blob))
|
195 |
image.thumbnail((30, 30))
|
196 |
buffered = BytesIO()
|
197 |
image.save(buffered, format="png")
|
198 |
return buffered.getvalue()
|
199 |
|
200 |
+
elif re.match(r".*\.(ppt|pptx)$", filename):
|
201 |
import aspose.slides as slides
|
202 |
import aspose.pydrawing as drawing
|
203 |
try:
|
204 |
with slides.Presentation(BytesIO(blob)) as presentation:
|
205 |
buffered = BytesIO()
|
206 |
+
scale = 0.03
|
207 |
+
img = None
|
208 |
+
for _ in range(10):
|
209 |
+
# https://reference.aspose.com/slides/python-net/aspose.slides/slide/get_thumbnail/#float-float
|
210 |
+
presentation.slides[0].get_thumbnail(scale, scale).save(
|
211 |
+
buffered, drawing.imaging.ImageFormat.png)
|
212 |
+
img = buffered.getvalue()
|
213 |
+
if len(img) >= 64000:
|
214 |
+
scale = scale / 2.0
|
215 |
+
buffered = BytesIO()
|
216 |
+
else:
|
217 |
+
break
|
218 |
+
return img
|
219 |
except Exception:
|
220 |
pass
|
221 |
return None
|