mirror of
https://github.com/TagStudioDev/TagStudio.git
synced 2026-02-01 07:39:10 +00:00
Merge branch 'text-thumbnails'
This commit is contained in:
BIN
tagstudio/resources/qt/images/thumb_file_default_512.png
Normal file
BIN
tagstudio/resources/qt/images/thumb_file_default_512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -191,7 +191,7 @@ class CliDriver:
|
||||
return WHITE_FG
|
||||
elif ext.lower().replace('.','',1) in VIDEO_TYPES:
|
||||
return BRIGHT_CYAN_FG
|
||||
elif ext.lower().replace('.','',1) in TEXT_TYPES:
|
||||
elif ext.lower().replace('.','',1) in DOC_TYPES:
|
||||
return BRIGHT_GREEN_FG
|
||||
else:
|
||||
return BRIGHT_WHITE_FG
|
||||
|
||||
@@ -18,6 +18,7 @@ BACKUP_FOLDER_NAME: str = 'backups'
|
||||
COLLAGE_FOLDER_NAME: str = 'collages'
|
||||
LIBRARY_FILENAME: str = 'ts_library.json'
|
||||
|
||||
# TODO: Turn this whitelist into a user-configurable blacklist.
|
||||
IMAGE_TYPES: list[str] = ['png', 'jpg', 'jpeg', 'jpg_large', 'jpeg_large',
|
||||
'jfif', 'gif', 'tif', 'tiff', 'heic', 'heif', 'webp',
|
||||
'bmp', 'svg', 'avif', 'apng', 'jp2', 'j2k', 'jpg2']
|
||||
@@ -25,8 +26,10 @@ VIDEO_TYPES: list[str] = ['mp4', 'webm', 'mov', 'hevc', 'mkv', 'avi', 'wmv',
|
||||
'flv', 'gifv', 'm4p', 'm4v', '3gp']
|
||||
AUDIO_TYPES: list[str] = ['mp3', 'mp4', 'mpeg4', 'm4a', 'aac', 'wav', 'flac',
|
||||
'alac', 'wma', 'ogg', 'aiff']
|
||||
TEXT_TYPES: list[str] = ['txt', 'rtf', 'md',
|
||||
DOC_TYPES: list[str] = ['txt', 'rtf', 'md',
|
||||
'doc', 'docx', 'pdf', 'tex', 'odt', 'pages']
|
||||
PLAINTEXT_TYPES: list[str] = ['txt', 'md', 'css', 'html', 'xml', 'json', 'js',
|
||||
'ts', 'ini', 'htm', 'csv', 'php', 'sh', 'bat']
|
||||
SPREADSHEET_TYPES: list[str] = ['csv', 'xls', 'xlsx', 'numbers', 'ods']
|
||||
PRESENTATION_TYPES: list[str] = ['ppt', 'pptx', 'key', 'odp']
|
||||
ARCHIVE_TYPES: list[str] = ['zip', 'rar', 'tar', 'tar.gz', 'tgz', '7z']
|
||||
@@ -34,7 +37,7 @@ PROGRAM_TYPES: list[str] = ['exe', 'app']
|
||||
SHORTCUT_TYPES: list[str] = ['lnk', 'desktop', 'url']
|
||||
|
||||
ALL_FILE_TYPES: list[str] = IMAGE_TYPES + VIDEO_TYPES + AUDIO_TYPES + \
|
||||
TEXT_TYPES + SPREADSHEET_TYPES + PRESENTATION_TYPES + \
|
||||
DOC_TYPES + SPREADSHEET_TYPES + PRESENTATION_TYPES + \
|
||||
ARCHIVE_TYPES + PROGRAM_TYPES + SHORTCUT_TYPES
|
||||
|
||||
BOX_FIELDS = ['tag_box', 'text_box']
|
||||
|
||||
@@ -38,9 +38,9 @@ from humanfriendly import format_timespan, format_size
|
||||
|
||||
from src.core.library import Collation, Entry, ItemType, Library, Tag
|
||||
from src.core.palette import ColorType, get_tag_color
|
||||
from src.core.ts_core import (TagStudioCore, TAG_COLORS, DATE_FIELDS, TEXT_FIELDS, BOX_FIELDS, ALL_FILE_TYPES,
|
||||
from src.core.ts_core import (PLAINTEXT_TYPES, TagStudioCore, TAG_COLORS, DATE_FIELDS, TEXT_FIELDS, BOX_FIELDS, ALL_FILE_TYPES,
|
||||
SHORTCUT_TYPES, PROGRAM_TYPES, ARCHIVE_TYPES, PRESENTATION_TYPES,
|
||||
SPREADSHEET_TYPES, TEXT_TYPES, AUDIO_TYPES, VIDEO_TYPES, IMAGE_TYPES,
|
||||
SPREADSHEET_TYPES, DOC_TYPES, AUDIO_TYPES, VIDEO_TYPES, IMAGE_TYPES,
|
||||
LIBRARY_FILENAME, COLLAGE_FOLDER_NAME, BACKUP_FOLDER_NAME, TS_FOLDER_NAME,
|
||||
VERSION_BRANCH, VERSION)
|
||||
from src.core.utils.web import strip_web_protocol
|
||||
@@ -3434,7 +3434,7 @@ class CollageIconRenderer(QObject):
|
||||
return '\033[37m'
|
||||
elif ext.lower().replace('.','',1) in VIDEO_TYPES:
|
||||
return '\033[96m'
|
||||
elif ext.lower().replace('.','',1) in TEXT_TYPES:
|
||||
elif ext.lower().replace('.','',1) in DOC_TYPES:
|
||||
return '\033[92m'
|
||||
else:
|
||||
return '\033[97m'
|
||||
@@ -3462,6 +3462,10 @@ class ThumbRenderer(QObject):
|
||||
f'{Path(__file__).parent.parent.parent}/resources/qt/images/thumb_broken_512.png'))
|
||||
thumb_broken_512.load()
|
||||
|
||||
thumb_file_default_512: Image.Image = Image.open(os.path.normpath(
|
||||
f'{Path(__file__).parent.parent.parent}/resources/qt/images/thumb_file_default_512.png'))
|
||||
thumb_file_default_512.load()
|
||||
|
||||
# thumb_debug: Image.Image = Image.open(os.path.normpath(
|
||||
# f'{Path(__file__).parent.parent.parent}/resources/qt/images/temp.jpg'))
|
||||
# thumb_debug.load()
|
||||
@@ -3506,6 +3510,7 @@ class ThumbRenderer(QObject):
|
||||
extension = os.path.splitext(filepath)[1][1:].lower()
|
||||
|
||||
try:
|
||||
# Images =======================================================
|
||||
if extension in IMAGE_TYPES:
|
||||
image = Image.open(filepath)
|
||||
# image = self.thumb_debug
|
||||
@@ -3516,11 +3521,8 @@ class ThumbRenderer(QObject):
|
||||
image = new_bg
|
||||
if image.mode != 'RGB':
|
||||
image = image.convert(mode='RGB')
|
||||
# raise ValueError
|
||||
# except (UnidentifiedImageError, FileNotFoundError):
|
||||
# image = Image.open(os.path.normpath(f'{Path(__file__).parent.parent.parent}/resources/cli/images/no_preview.png'))
|
||||
# image.thumbnail((adj_size,adj_size))
|
||||
|
||||
# Videos =======================================================
|
||||
elif extension in VIDEO_TYPES:
|
||||
video = cv2.VideoCapture(filepath)
|
||||
video.set(cv2.CAP_PROP_POS_FRAMES,
|
||||
@@ -3534,11 +3536,23 @@ class ThumbRenderer(QObject):
|
||||
success, frame = video.read()
|
||||
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
||||
image = Image.fromarray(frame)
|
||||
|
||||
# TODO: Create placeholder thumbnails for non-media files.
|
||||
# else:
|
||||
# image: Image.Image = ThumbRenderer.thumb_loading_512.resize(
|
||||
# (adj_size, adj_size), resample=Image.Resampling.BILINEAR)
|
||||
|
||||
# Plain Text ===================================================
|
||||
elif extension in PLAINTEXT_TYPES:
|
||||
try:
|
||||
text: str = extension
|
||||
with open(filepath, 'r', encoding='utf-8') as text_file:
|
||||
text = text_file.read(256)
|
||||
bg = Image.new('RGB',(256,256), color='#222222')
|
||||
draw = ImageDraw.Draw(bg)
|
||||
draw.text((16,16), text, file=(255,255,255))
|
||||
image = bg
|
||||
except:
|
||||
logging.info(f'[ThumbRenderer][ERROR]: Coulnd\'t render thumbnail for {filepath}')
|
||||
# No Rendered Thumbnail ========================================
|
||||
else:
|
||||
image = ThumbRenderer.thumb_file_default_512.resize(
|
||||
(adj_size, adj_size), resample=Image.Resampling.BILINEAR)
|
||||
|
||||
if not image:
|
||||
raise UnidentifiedImageError
|
||||
@@ -3553,9 +3567,7 @@ class ThumbRenderer(QObject):
|
||||
new_y = adj_size
|
||||
new_x = math.ceil(adj_size * (orig_x / orig_y))
|
||||
|
||||
img_ratio = new_x / new_y
|
||||
# logging.info(f'[TR] {(new_x / new_y)}')
|
||||
# self.updated_ratio.emit(new_x / new_y)
|
||||
# img_ratio = new_x / new_y
|
||||
image = image.resize(
|
||||
(new_x, new_y), resample=Image.Resampling.BILINEAR)
|
||||
|
||||
@@ -3608,21 +3620,6 @@ class ThumbRenderer(QObject):
|
||||
final = ThumbRenderer.thumb_broken_512.resize(
|
||||
(adj_size, adj_size), resample=Image.Resampling.BILINEAR)
|
||||
|
||||
# if file_type in VIDEO_TYPES + ['gif', 'apng'] or broken_thumb:
|
||||
# idk = ImageDraw.Draw(final)
|
||||
# # idk.textlength(file_type)
|
||||
# ext_offset_x = idk.textlength(
|
||||
# text=file_type.upper(), font=ThumbRenderer.ext_font) / 2
|
||||
# ext_offset_x = math.floor(ext_offset_x * (1/pixelRatio))
|
||||
# x_margin = math.floor(
|
||||
# (adj_size-((base_size[0]//6)+ext_offset_x) * pixelRatio))
|
||||
# y_margin = math.floor(
|
||||
# (adj_size-((base_size[0]//8)) * pixelRatio))
|
||||
# stroke_width = round(2 * pixelRatio)
|
||||
# fill = 'white' if not broken_thumb else '#E32B41'
|
||||
# idk.text((x_margin, y_margin), file_type.upper(
|
||||
# ), fill=fill, font=ThumbRenderer.ext_font, stroke_width=stroke_width, stroke_fill=(0, 0, 0))
|
||||
|
||||
qim = ImageQt.ImageQt(final)
|
||||
if image:
|
||||
image.close()
|
||||
@@ -3672,6 +3669,7 @@ class ThumbRenderer(QObject):
|
||||
extension = os.path.splitext(filepath)[1][1:].lower()
|
||||
|
||||
try:
|
||||
# Images =======================================================
|
||||
if extension in IMAGE_TYPES:
|
||||
image = Image.open(filepath)
|
||||
# image = self.thumb_debug
|
||||
@@ -3682,11 +3680,8 @@ class ThumbRenderer(QObject):
|
||||
image = new_bg
|
||||
if image.mode != 'RGB':
|
||||
image = image.convert(mode='RGB')
|
||||
# raise ValueError
|
||||
# except (UnidentifiedImageError, FileNotFoundError):
|
||||
# image = Image.open(os.path.normpath(f'{Path(__file__).parent.parent.parent}/resources/cli/images/no_preview.png'))
|
||||
# image.thumbnail((adj_size,adj_size))
|
||||
|
||||
# Videos =======================================================
|
||||
elif extension in VIDEO_TYPES:
|
||||
video = cv2.VideoCapture(filepath)
|
||||
video.set(cv2.CAP_PROP_POS_FRAMES,
|
||||
@@ -3700,6 +3695,22 @@ class ThumbRenderer(QObject):
|
||||
success, frame = video.read()
|
||||
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
||||
image = Image.fromarray(frame)
|
||||
# Plain Text ===================================================
|
||||
elif extension in PLAINTEXT_TYPES:
|
||||
try:
|
||||
text: str = extension
|
||||
with open(filepath, 'r', encoding='utf-8') as text_file:
|
||||
text = text_file.read(256)
|
||||
bg = Image.new('RGB',(256,256), color='#222222')
|
||||
draw = ImageDraw.Draw(bg)
|
||||
draw.text((16,16), text, file=(255,255,255))
|
||||
image = bg
|
||||
except:
|
||||
logging.info(f'[ThumbRenderer][ERROR]: Coulnd\'t render thumbnail for {filepath}')
|
||||
# No Rendered Thumbnail ========================================
|
||||
else:
|
||||
image = ThumbRenderer.thumb_file_default_512.resize(
|
||||
(adj_size, adj_size), resample=Image.Resampling.BILINEAR)
|
||||
|
||||
if not image:
|
||||
raise UnidentifiedImageError
|
||||
|
||||
Reference in New Issue
Block a user