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
|