From dac3464c771694edf413398e6e8ea78288110848 Mon Sep 17 00:00:00 2001 From: Ethnogeny <111099761+050011-code@users.noreply.github.com> Date: Mon, 10 Jun 2024 19:31:28 +1000 Subject: [PATCH 01/16] Update thumb_renderer.py Included support for rendering blender thumbnails --- tagstudio/src/qt/widgets/thumb_renderer.py | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tagstudio/src/qt/widgets/thumb_renderer.py b/tagstudio/src/qt/widgets/thumb_renderer.py index 8198e9ffb..20a957746 100644 --- a/tagstudio/src/qt/widgets/thumb_renderer.py +++ b/tagstudio/src/qt/widgets/thumb_renderer.py @@ -204,6 +204,39 @@ def render( # img_buf = io.BytesIO() # plt.savefig(img_buf, format='png') # image = Image.open(img_buf) + + # Blender =========================================================== + elif _filepath.suffix.lower() == '.blend': + from src.qt.helpers import blender_thumbnailer + + try: + blendthumbnail = blender_thumbnailer.main(str(_filepath)) + image = Image.frombuffer("RGBA",(blendthumbnail[1],blendthumbnail[2]),blendthumbnail[0]) + image = ImageOps.flip(image) + image = ImageOps.exif_transpose(image) + + except ( + AttributeError, + UnidentifiedImageError, + FileNotFoundError, + DecompressionBombError, + UnicodeDecodeError, TypeError) as e: + + if str(e) == "expected string or buffer": + logging.info(f"[ThumbRenderer]{ERROR} Can't read the blender thumbnail of {_filepath.name}. Unlucky.") + + + else: + logging.info(f"[ThumbRenderer]{ERROR}: Couldn't render thumbnail for {_filepath.name} ({type(e).__name__})") + + font_path = "./resources/qt/fonts/Oxanium-Bold.ttf" + font = ImageFont.truetype(font_path, 17) + bg = Image.new("RGB", (256, 256), color="#1e1e1e") + draw = ImageDraw.Draw(bg) + draw.text((16, 16), "Can't read blend thumbnail", file=(255, 255, 255), font=font) + image = bg + + # No Rendered Thumbnail ======================================== else: image = ThumbRenderer.thumb_file_default_512.resize( From a55be5d353e91fa26f6a581f247d226af9b4535f Mon Sep 17 00:00:00 2001 From: Ethnogeny <111099761+050011-code@users.noreply.github.com> Date: Mon, 10 Jun 2024 19:33:23 +1000 Subject: [PATCH 02/16] Add files via upload Add functions that get the thumbnail's data --- .../src/qt/helpers/blender_thumbnailer.py | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 tagstudio/src/qt/helpers/blender_thumbnailer.py diff --git a/tagstudio/src/qt/helpers/blender_thumbnailer.py b/tagstudio/src/qt/helpers/blender_thumbnailer.py new file mode 100644 index 000000000..80a9f753b --- /dev/null +++ b/tagstudio/src/qt/helpers/blender_thumbnailer.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python3 + +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# + + +## This file is a modified script that gets the thumbnail data stored in a blend file + + +import struct + + +def open_wrapper_get(): + """ wrap OS specific read functionality here, fallback to 'open()' + """ + + class GFileWrapper: + __slots__ = ("mode", "g_file") + + def __init__(self, url, mode='r'): + self.mode = mode # used in gzip module + self.g_file = Gio.File.parse_name(url).read(None) + + def read(self, size): + return self.g_file.read_bytes(size, None).get_data() + + def seek(self, offset, whence=0): + self.g_file.seek(offset, [1, 0, 2][whence], None) + return self.g_file.tell() + + def tell(self): + return self.g_file.tell() + + def close(self): + self.g_file.close(None) + + def open_local_url(url, mode='r'): + + path = url + + return open(str(path), mode) + + try: + from gi.repository import Gio + return GFileWrapper + except ImportError: + try: + # Python 3 + from urllib.parse import urlparse, unquote + except ImportError: + # Python 2 + from urlparse import urlparse + from urllib import unquote + return open_local_url + + +def blend_extract_thumb(path): + import os + open_wrapper = open_wrapper_get() + + REND = b'REND' + TEST = b'TEST' + + blendfile = open_wrapper(path, 'rb') + + head = blendfile.read(12) + + if head[0:2] == b'\x1f\x8b': # gzip magic + import gzip + blendfile.close() + blendfile = gzip.GzipFile('', 'rb', 0, open_wrapper(path, 'rb')) + head = blendfile.read(12) + + if not head.startswith(b'BLENDER'): + blendfile.close() + return None, 0, 0 + + is_64_bit = (head[7] == b'-'[0]) + + # true for PPC, false for X86 + is_big_endian = (head[8] == b'V'[0]) + + # blender pre 2.5 had no thumbs + if head[9:11] <= b'24': + return None, 0, 0 + + sizeof_bhead = 24 if is_64_bit else 20 + int_endian = '>i' if is_big_endian else ' Date: Tue, 11 Jun 2024 08:55:01 +1000 Subject: [PATCH 03/16] Update thumb_renderer.py --- tagstudio/src/qt/widgets/thumb_renderer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tagstudio/src/qt/widgets/thumb_renderer.py b/tagstudio/src/qt/widgets/thumb_renderer.py index 20a957746..135437641 100644 --- a/tagstudio/src/qt/widgets/thumb_renderer.py +++ b/tagstudio/src/qt/widgets/thumb_renderer.py @@ -229,6 +229,7 @@ def render( else: logging.info(f"[ThumbRenderer]{ERROR}: Couldn't render thumbnail for {_filepath.name} ({type(e).__name__})") + # Making the "No blend thumbnail avaliable" thumbnail font_path = "./resources/qt/fonts/Oxanium-Bold.ttf" font = ImageFont.truetype(font_path, 17) bg = Image.new("RGB", (256, 256), color="#1e1e1e") From e285b0d8d4aa6b88421a714e553399f01ca27467 Mon Sep 17 00:00:00 2001 From: Ethnogeny <111099761+050011-code@users.noreply.github.com> Date: Tue, 11 Jun 2024 08:56:32 +1000 Subject: [PATCH 04/16] Update blender_thumbnailer.py --- tagstudio/src/qt/helpers/blender_thumbnailer.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tagstudio/src/qt/helpers/blender_thumbnailer.py b/tagstudio/src/qt/helpers/blender_thumbnailer.py index 80a9f753b..4585e54b8 100644 --- a/tagstudio/src/qt/helpers/blender_thumbnailer.py +++ b/tagstudio/src/qt/helpers/blender_thumbnailer.py @@ -53,6 +53,8 @@ def close(self): def open_local_url(url, mode='r'): + # Redundant af, but this is where the checking of file names can be done + path = url return open(str(path), mode) From 3e365568669f492be533199047a6fcdc45b565ff Mon Sep 17 00:00:00 2001 From: Ethnogeny <111099761+050011-code@users.noreply.github.com> Date: Tue, 11 Jun 2024 08:58:45 +1000 Subject: [PATCH 05/16] Update thumb_renderer.py --- tagstudio/src/qt/widgets/thumb_renderer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tagstudio/src/qt/widgets/thumb_renderer.py b/tagstudio/src/qt/widgets/thumb_renderer.py index 135437641..8dff4ffd0 100644 --- a/tagstudio/src/qt/widgets/thumb_renderer.py +++ b/tagstudio/src/qt/widgets/thumb_renderer.py @@ -223,7 +223,7 @@ def render( UnicodeDecodeError, TypeError) as e: if str(e) == "expected string or buffer": - logging.info(f"[ThumbRenderer]{ERROR} Can't read the blender thumbnail of {_filepath.name}. Unlucky.") + logging.info(f"[ThumbRenderer]{ERROR} Can't read the blender thumbnail of {_filepath.name}. Either deleted or doesn't have a thumbnail.") else: From 5fbff3898df0a44459c691c38c10657d487ded79 Mon Sep 17 00:00:00 2001 From: Ethnogeny <111099761+050011-code@users.noreply.github.com> Date: Tue, 11 Jun 2024 17:29:07 +1000 Subject: [PATCH 06/16] Update thumb_renderer.py Changed where imports are according to feedback --- tagstudio/src/qt/widgets/thumb_renderer.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tagstudio/src/qt/widgets/thumb_renderer.py b/tagstudio/src/qt/widgets/thumb_renderer.py index 8dff4ffd0..67c93c6cd 100644 --- a/tagstudio/src/qt/widgets/thumb_renderer.py +++ b/tagstudio/src/qt/widgets/thumb_renderer.py @@ -30,6 +30,7 @@ RAW_IMAGE_TYPES, ) from src.core.utils.encoding import detect_char_encoding +from src.qt.helpers.blender_thumbnailer import main ImageFile.LOAD_TRUNCATED_IMAGES = True @@ -206,9 +207,7 @@ def render( # image = Image.open(img_buf) # Blender =========================================================== - elif _filepath.suffix.lower() == '.blend': - from src.qt.helpers import blender_thumbnailer - + elif _filepath.suffix.lower() == '.blend': try: blendthumbnail = blender_thumbnailer.main(str(_filepath)) image = Image.frombuffer("RGBA",(blendthumbnail[1],blendthumbnail[2]),blendthumbnail[0]) From 699e7d4cc04b0c3422003623e5fe7260f6b1b2bd Mon Sep 17 00:00:00 2001 From: Ethnogeny <111099761+050011-code@users.noreply.github.com> Date: Tue, 11 Jun 2024 17:37:19 +1000 Subject: [PATCH 07/16] Update thumb_renderer.py Changed blender thumbnail function name to reduce ambiguity --- tagstudio/src/qt/widgets/thumb_renderer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tagstudio/src/qt/widgets/thumb_renderer.py b/tagstudio/src/qt/widgets/thumb_renderer.py index 67c93c6cd..47718d1ca 100644 --- a/tagstudio/src/qt/widgets/thumb_renderer.py +++ b/tagstudio/src/qt/widgets/thumb_renderer.py @@ -30,7 +30,7 @@ RAW_IMAGE_TYPES, ) from src.core.utils.encoding import detect_char_encoding -from src.qt.helpers.blender_thumbnailer import main +from src.qt.helpers.blender_thumbnailer import blendthumb ImageFile.LOAD_TRUNCATED_IMAGES = True @@ -209,7 +209,7 @@ def render( # Blender =========================================================== elif _filepath.suffix.lower() == '.blend': try: - blendthumbnail = blender_thumbnailer.main(str(_filepath)) + blendthumbnail = blendthumb(str(_filepath)) image = Image.frombuffer("RGBA",(blendthumbnail[1],blendthumbnail[2]),blendthumbnail[0]) image = ImageOps.flip(image) image = ImageOps.exif_transpose(image) From 33940b5fb49243f7f7a5c5cc714df62e2621fb05 Mon Sep 17 00:00:00 2001 From: Ethnogeny <111099761+050011-code@users.noreply.github.com> Date: Tue, 11 Jun 2024 17:37:54 +1000 Subject: [PATCH 08/16] Update blender_thumbnailer.py Updated function name --- tagstudio/src/qt/helpers/blender_thumbnailer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tagstudio/src/qt/helpers/blender_thumbnailer.py b/tagstudio/src/qt/helpers/blender_thumbnailer.py index 4585e54b8..b739a66bb 100644 --- a/tagstudio/src/qt/helpers/blender_thumbnailer.py +++ b/tagstudio/src/qt/helpers/blender_thumbnailer.py @@ -164,6 +164,6 @@ def blend_extract_thumb(path): -def main(file_in): +def blendthumb(file_in): buf, width, height = blend_extract_thumb(file_in) return [buf, width, height] From 5b6fad91ece4aed074d83bfecbedcfaebe91014f Mon Sep 17 00:00:00 2001 From: Ethnogeny <111099761+050011-code@users.noreply.github.com> Date: Wed, 12 Jun 2024 15:31:26 +1000 Subject: [PATCH 09/16] Update blender_thumbnailer.py --- .../src/qt/helpers/blender_thumbnailer.py | 67 +++++-------------- 1 file changed, 18 insertions(+), 49 deletions(-) diff --git a/tagstudio/src/qt/helpers/blender_thumbnailer.py b/tagstudio/src/qt/helpers/blender_thumbnailer.py index b739a66bb..11ff033c3 100644 --- a/tagstudio/src/qt/helpers/blender_thumbnailer.py +++ b/tagstudio/src/qt/helpers/blender_thumbnailer.py @@ -28,84 +28,54 @@ def open_wrapper_get(): - """ wrap OS specific read functionality here, fallback to 'open()' - """ + """wrap OS specific read functionality here, fallback to 'open()'""" - class GFileWrapper: - __slots__ = ("mode", "g_file") - - def __init__(self, url, mode='r'): - self.mode = mode # used in gzip module - self.g_file = Gio.File.parse_name(url).read(None) - - def read(self, size): - return self.g_file.read_bytes(size, None).get_data() - - def seek(self, offset, whence=0): - self.g_file.seek(offset, [1, 0, 2][whence], None) - return self.g_file.tell() - - def tell(self): - return self.g_file.tell() - - def close(self): - self.g_file.close(None) - - def open_local_url(url, mode='r'): - - # Redundant af, but this is where the checking of file names can be done + def open_local_url(url, mode="r"): + # Redundant af, but this is where the checking of file path can be done path = url return open(str(path), mode) - try: - from gi.repository import Gio - return GFileWrapper - except ImportError: - try: - # Python 3 - from urllib.parse import urlparse, unquote - except ImportError: - # Python 2 - from urlparse import urlparse - from urllib import unquote - return open_local_url + + return open_local_url def blend_extract_thumb(path): import os + open_wrapper = open_wrapper_get() - REND = b'REND' - TEST = b'TEST' + REND = b"REND" + TEST = b"TEST" - blendfile = open_wrapper(path, 'rb') + blendfile = open_wrapper(path, "rb") head = blendfile.read(12) - if head[0:2] == b'\x1f\x8b': # gzip magic + if head[0:2] == b"\x1f\x8b": # gzip magic import gzip + blendfile.close() - blendfile = gzip.GzipFile('', 'rb', 0, open_wrapper(path, 'rb')) + blendfile = gzip.GzipFile("", "rb", 0, open_wrapper(path, "rb")) head = blendfile.read(12) - if not head.startswith(b'BLENDER'): + if not head.startswith(b"BLENDER"): blendfile.close() return None, 0, 0 - is_64_bit = (head[7] == b'-'[0]) + is_64_bit = head[7] == b"-"[0] # true for PPC, false for X86 - is_big_endian = (head[8] == b'V'[0]) + is_big_endian = head[8] == b"V"[0] # blender pre 2.5 had no thumbs - if head[9:11] <= b'24': + if head[9:11] <= b"24": return None, 0, 0 sizeof_bhead = 24 if is_64_bit else 20 - int_endian = '>i' if is_big_endian else ' Date: Thu, 13 Jun 2024 08:45:29 +1000 Subject: [PATCH 10/16] Update blender_thumbnailer.py Ruff format --- tagstudio/src/qt/helpers/blender_thumbnailer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tagstudio/src/qt/helpers/blender_thumbnailer.py b/tagstudio/src/qt/helpers/blender_thumbnailer.py index 11ff033c3..bbad0c6b5 100644 --- a/tagstudio/src/qt/helpers/blender_thumbnailer.py +++ b/tagstudio/src/qt/helpers/blender_thumbnailer.py @@ -37,7 +37,6 @@ def open_local_url(url, mode="r"): return open(str(path), mode) - return open_local_url From 0ab4348bf289e1f0e6308e745389c74400cea2bc Mon Sep 17 00:00:00 2001 From: Ethnogeny <111099761+050011-code@users.noreply.github.com> Date: Thu, 13 Jun 2024 08:46:33 +1000 Subject: [PATCH 11/16] Update thumb_renderer.py Ruff format --- tagstudio/src/qt/widgets/thumb_renderer.py | 34 +++++++++++++++------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/tagstudio/src/qt/widgets/thumb_renderer.py b/tagstudio/src/qt/widgets/thumb_renderer.py index 47718d1ca..4a50f858c 100644 --- a/tagstudio/src/qt/widgets/thumb_renderer.py +++ b/tagstudio/src/qt/widgets/thumb_renderer.py @@ -207,36 +207,48 @@ def render( # image = Image.open(img_buf) # Blender =========================================================== - elif _filepath.suffix.lower() == '.blend': + elif _filepath.suffix.lower() == ".blend": try: blendthumbnail = blendthumb(str(_filepath)) - image = Image.frombuffer("RGBA",(blendthumbnail[1],blendthumbnail[2]),blendthumbnail[0]) + image = Image.frombuffer( + "RGBA", + (blendthumbnail[1], blendthumbnail[2]), + blendthumbnail[0], + ) image = ImageOps.flip(image) image = ImageOps.exif_transpose(image) - + except ( AttributeError, UnidentifiedImageError, FileNotFoundError, DecompressionBombError, - UnicodeDecodeError, TypeError) as e: - + UnicodeDecodeError, + TypeError, + ) as e: if str(e) == "expected string or buffer": - logging.info(f"[ThumbRenderer]{ERROR} Can't read the blender thumbnail of {_filepath.name}. Either deleted or doesn't have a thumbnail.") - + logging.info( + f"[ThumbRenderer]{ERROR} Can't read the blender thumbnail of {_filepath.name}. Either deleted or doesn't have a thumbnail." + ) else: - logging.info(f"[ThumbRenderer]{ERROR}: Couldn't render thumbnail for {_filepath.name} ({type(e).__name__})") + logging.info( + f"[ThumbRenderer]{ERROR}: Couldn't render thumbnail for {_filepath.name} ({type(e).__name__})" + ) # Making the "No blend thumbnail avaliable" thumbnail font_path = "./resources/qt/fonts/Oxanium-Bold.ttf" font = ImageFont.truetype(font_path, 17) bg = Image.new("RGB", (256, 256), color="#1e1e1e") draw = ImageDraw.Draw(bg) - draw.text((16, 16), "Can't read blend thumbnail", file=(255, 255, 255), font=font) + draw.text( + (16, 16), + "Can't read blend thumbnail", + file=(255, 255, 255), + font=font, + ) image = bg - - + # No Rendered Thumbnail ======================================== else: image = ThumbRenderer.thumb_file_default_512.resize( From 21573e87856ad3e68c2dcf7f599f8ceb273f975f Mon Sep 17 00:00:00 2001 From: Ethnogeny <111099761+050011-code@users.noreply.github.com> Date: Wed, 19 Jun 2024 10:29:41 +1000 Subject: [PATCH 12/16] Update constants.py Add .blend1, 2, 3 etc file support --- tagstudio/src/core/constants.py | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tagstudio/src/core/constants.py b/tagstudio/src/core/constants.py index d07489aa6..509ae1e84 100644 --- a/tagstudio/src/core/constants.py +++ b/tagstudio/src/core/constants.py @@ -105,6 +105,41 @@ ".7z", ".s7z", ] +BLENDER_TYPES: list[str] = [ + ".blend", + ".blend1", + ".blend2", + ".blend3", + ".blend4", + ".blend5", + ".blend6", + ".blend7", + ".blend8", + ".blend9", + ".blend10", + ".blend11", + ".blend12", + ".blend13", + ".blend14", + ".blend15", + ".blend16", + ".blend17", + ".blend18", + ".blend19", + ".blend20", + ".blend21", + ".blend22", + ".blend23", + ".blend24", + ".blend25", + ".blend26", + ".blend27", + ".blend28", + ".blend29", + ".blend30", + ".blend31", + ".blend32", +] PROGRAM_TYPES: list[str] = [".exe", ".app"] SHORTCUT_TYPES: list[str] = [".lnk", ".desktop", ".url"] From f7e9da31c4eecd9d51b6f719fa2325ea4313dae3 Mon Sep 17 00:00:00 2001 From: Ethnogeny <111099761+050011-code@users.noreply.github.com> Date: Wed, 19 Jun 2024 10:31:07 +1000 Subject: [PATCH 13/16] Update blender_thumbnailer.py Refactor to follow requested changes --- .../src/qt/helpers/blender_thumbnailer.py | 61 ++++++------------- 1 file changed, 17 insertions(+), 44 deletions(-) diff --git a/tagstudio/src/qt/helpers/blender_thumbnailer.py b/tagstudio/src/qt/helpers/blender_thumbnailer.py index bbad0c6b5..09bced753 100644 --- a/tagstudio/src/qt/helpers/blender_thumbnailer.py +++ b/tagstudio/src/qt/helpers/blender_thumbnailer.py @@ -25,38 +25,26 @@ import struct - - -def open_wrapper_get(): - """wrap OS specific read functionality here, fallback to 'open()'""" - - def open_local_url(url, mode="r"): - # Redundant af, but this is where the checking of file path can be done - - path = url - - return open(str(path), mode) - - return open_local_url +from PIL import ( + Image, + ImageOps, +) +import gzip +import os def blend_extract_thumb(path): - import os - - open_wrapper = open_wrapper_get() - + REND = b"REND" TEST = b"TEST" - blendfile = open_wrapper(path, "rb") + blendfile = open(path, "rb") head = blendfile.read(12) if head[0:2] == b"\x1f\x8b": # gzip magic - import gzip - blendfile.close() - blendfile = gzip.GzipFile("", "rb", 0, open_wrapper(path, "rb")) + blendfile = gzip.GzipFile("", "rb", 0, open(path, "rb")) head = blendfile.read(12) if not head.startswith(b"BLENDER"): @@ -111,27 +99,12 @@ def blend_extract_thumb(path): return image_buffer, x, y -# Trying to flip image buffer to have the image right way round on the output, but can't figure it out -# Currently, just flipping it with ImageOps in the thumbnail_renderer.py - -##def flip_image(buf, width, height): -## import zlib -## -## # reverse the vertical line order and add null bytes at the start -## width_byte_4 = width * 4 -## raw_data = b"".join(b'\x00' + buf[span:span + width_byte_4] for span in range((height - 1) * width * 4, -1, - width_byte_4)) -## -## def png_pack(png_tag, data): -## chunk_head = png_tag + data -## return struct.pack("!I", len(data)) + chunk_head + struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head)) -## -## return [b"".join([ -## b'\x89PNG\r\n\x1a\n', -## png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)), -## png_pack(b'IDAT', zlib.compress(raw_data, 9)), -## png_pack(b'IEND', b'')]), width, height] - - -def blendthumb(file_in): +def blend_thumb(file_in): buf, width, height = blend_extract_thumb(file_in) - return [buf, width, height] + image = Image.frombuffer( + "RGBA", + (width, height), + buf, + ) + image = ImageOps.flip(image) + return image From efaa89b26a8996bb61b14946ecd2751958a9aabc Mon Sep 17 00:00:00 2001 From: Ethnogeny <111099761+050011-code@users.noreply.github.com> Date: Wed, 19 Jun 2024 10:32:41 +1000 Subject: [PATCH 14/16] Update thumb_renderer.py More refactoring --- tagstudio/src/qt/widgets/thumb_renderer.py | 37 +++++++--------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/tagstudio/src/qt/widgets/thumb_renderer.py b/tagstudio/src/qt/widgets/thumb_renderer.py index ef87f7aa7..04ca61519 100644 --- a/tagstudio/src/qt/widgets/thumb_renderer.py +++ b/tagstudio/src/qt/widgets/thumb_renderer.py @@ -28,9 +28,10 @@ VIDEO_TYPES, IMAGE_TYPES, RAW_IMAGE_TYPES, + BLENDER_TYPES, ) from src.core.utils.encoding import detect_char_encoding -from src.qt.helpers.blender_thumbnailer import blendthumb +from src.qt.helpers.blender_thumbnailer import blend_thumb ImageFile.LOAD_TRUNCATED_IMAGES = True @@ -207,28 +208,23 @@ def render( # image = Image.open(img_buf) # Blender =========================================================== - elif _filepath.suffix.lower() == ".blend": + elif _filepath.suffix.lower() in BLENDER_TYPES: try: - blendthumbnail = blendthumb(str(_filepath)) - image = Image.frombuffer( - "RGBA", - (blendthumbnail[1], blendthumbnail[2]), - blendthumbnail[0], - ) - image = ImageOps.flip(image) - image = ImageOps.exif_transpose(image) + blend_image = blend_thumb(str(_filepath)) + bg = Image.new("RGB", blend_image.size, color="#1e1e1e") + bg.paste(blend_image, mask=blend_image.getchannel(3)) + image = bg + except ( AttributeError, UnidentifiedImageError, FileNotFoundError, - DecompressionBombError, - UnicodeDecodeError, TypeError, ) as e: if str(e) == "expected string or buffer": logging.info( - f"[ThumbRenderer]{ERROR} Can't read the blender thumbnail of {_filepath.name}. Either deleted or doesn't have a thumbnail." + f"[ThumbRenderer]{ERROR} {_filepath.name} Doesn't have thumbnail saved. ({type(e).__name__})" ) else: @@ -236,18 +232,9 @@ def render( f"[ThumbRenderer]{ERROR}: Couldn't render thumbnail for {_filepath.name} ({type(e).__name__})" ) - # Making the "No blend thumbnail avaliable" thumbnail - font_path = "./resources/qt/fonts/Oxanium-Bold.ttf" - font = ImageFont.truetype(font_path, 17) - bg = Image.new("RGB", (256, 256), color="#1e1e1e") - draw = ImageDraw.Draw(bg) - draw.text( - (16, 16), - "Can't read blend thumbnail", - file=(255, 255, 255), - font=font, - ) - image = bg + image = ThumbRenderer.thumb_file_default_512.resize( + (adj_size, adj_size), resample=Image.Resampling.BILINEAR + ) # No Rendered Thumbnail ======================================== else: From acbeb20105331ff4d24a75ace20a1a2935f0993b Mon Sep 17 00:00:00 2001 From: Ethnogeny <111099761+050011-code@users.noreply.github.com> Date: Wed, 19 Jun 2024 10:36:58 +1000 Subject: [PATCH 15/16] Update blender_thumbnailer.py Ruff format --- tagstudio/src/qt/helpers/blender_thumbnailer.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tagstudio/src/qt/helpers/blender_thumbnailer.py b/tagstudio/src/qt/helpers/blender_thumbnailer.py index 09bced753..89f171589 100644 --- a/tagstudio/src/qt/helpers/blender_thumbnailer.py +++ b/tagstudio/src/qt/helpers/blender_thumbnailer.py @@ -34,7 +34,6 @@ def blend_extract_thumb(path): - REND = b"REND" TEST = b"TEST" @@ -105,6 +104,6 @@ def blend_thumb(file_in): "RGBA", (width, height), buf, - ) + ) image = ImageOps.flip(image) return image From a540c0538a642c21ad1753221a7b3f4b6bf7ded0 Mon Sep 17 00:00:00 2001 From: Ethnogeny <111099761+050011-code@users.noreply.github.com> Date: Wed, 19 Jun 2024 10:38:03 +1000 Subject: [PATCH 16/16] Update thumb_renderer.py Ruff format --- tagstudio/src/qt/widgets/thumb_renderer.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tagstudio/src/qt/widgets/thumb_renderer.py b/tagstudio/src/qt/widgets/thumb_renderer.py index 04ca61519..9ed612c98 100644 --- a/tagstudio/src/qt/widgets/thumb_renderer.py +++ b/tagstudio/src/qt/widgets/thumb_renderer.py @@ -215,7 +215,7 @@ def render( bg = Image.new("RGB", blend_image.size, color="#1e1e1e") bg.paste(blend_image, mask=blend_image.getchannel(3)) image = bg - + except ( AttributeError, UnidentifiedImageError, @@ -233,8 +233,8 @@ def render( ) image = ThumbRenderer.thumb_file_default_512.resize( - (adj_size, adj_size), resample=Image.Resampling.BILINEAR - ) + (adj_size, adj_size), resample=Image.Resampling.BILINEAR + ) # No Rendered Thumbnail ======================================== else: