mirror of
https://github.com/TagStudioDev/TagStudio.git
synced 2026-02-02 16:19:10 +00:00
* feat: add svg thumbnail support Co-Authored-By: Tyrannicodin <86689800+Tyrannicodin@users.noreply.github.com> * flip `svg.isValid()` logic check * tests: add test comparing svg to png snapshot Co-Authored-By: yed <yedpodtrzitko@users.noreply.github.com> --------- Co-authored-by: Tyrannicodin <86689800+Tyrannicodin@users.noreply.github.com> Co-authored-by: yed <yedpodtrzitko@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
5b85462cfa
commit
9255a86ad1
@@ -28,8 +28,9 @@ from PIL import (
|
||||
from PIL.Image import DecompressionBombError
|
||||
from pillow_heif import register_avif_opener, register_heif_opener
|
||||
from pydub import exceptions
|
||||
from PySide6.QtCore import QObject, QSize, Qt, Signal
|
||||
from PySide6.QtGui import QGuiApplication, QPixmap
|
||||
from PySide6.QtCore import QBuffer, QObject, QSize, Qt, Signal
|
||||
from PySide6.QtGui import QGuiApplication, QImage, QPainter, QPixmap
|
||||
from PySide6.QtSvg import QSvgRenderer
|
||||
from src.core.constants import FONT_SAMPLE_SIZES, FONT_SAMPLE_TEXT
|
||||
from src.core.media_types import MediaCategories, MediaType
|
||||
from src.core.palette import ColorType, UiColor, get_ui_color
|
||||
@@ -750,8 +751,33 @@ class ThumbRenderer(QObject):
|
||||
filepath (Path): The path of the file.
|
||||
size (tuple[int,int]): The size of the thumbnail.
|
||||
"""
|
||||
# TODO: Implement.
|
||||
im: Image.Image = None
|
||||
# Create an image to draw the svg to and a painter to do the drawing
|
||||
image: QImage = QImage(size, size, QImage.Format.Format_ARGB32)
|
||||
image.fill("#1e1e1e")
|
||||
|
||||
# Create an svg renderer, then render to the painter
|
||||
svg: QSvgRenderer = QSvgRenderer(str(filepath))
|
||||
|
||||
if not svg.isValid():
|
||||
raise UnidentifiedImageError
|
||||
|
||||
painter: QPainter = QPainter(image)
|
||||
svg.setAspectRatioMode(Qt.AspectRatioMode.KeepAspectRatio)
|
||||
svg.render(painter)
|
||||
painter.end()
|
||||
|
||||
# Write the image to a buffer as png
|
||||
buffer: QBuffer = QBuffer()
|
||||
buffer.open(QBuffer.OpenModeFlag.ReadWrite)
|
||||
image.save(buffer, "PNG")
|
||||
|
||||
# Load the image from the buffer
|
||||
im = Image.new("RGB", (size, size), color="#1e1e1e")
|
||||
im.paste(Image.open(BytesIO(buffer.data().data())))
|
||||
im = im.convert(mode="RGB")
|
||||
|
||||
buffer.close()
|
||||
return im
|
||||
|
||||
def _model_stl_thumb(self, filepath: Path, size: int) -> Image.Image:
|
||||
@@ -924,6 +950,7 @@ class ThumbRenderer(QObject):
|
||||
ext, MediaCategories.IMAGE_RAW_TYPES, mime_fallback=True
|
||||
):
|
||||
image = self._image_raw_thumb(_filepath)
|
||||
# Vector Images --------------------------------------------
|
||||
elif MediaCategories.is_ext_in_category(
|
||||
ext, MediaCategories.IMAGE_VECTOR_TYPES, mime_fallback=True
|
||||
):
|
||||
|
||||
8
tagstudio/tests/fixtures/sample.svg
vendored
Normal file
8
tagstudio/tests/fixtures/sample.svg
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 739 739" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path d="M392.721,715.585C422.869,745.733 471.822,745.733 501.97,715.585C521.252,696.304 698.205,519.351 715.585,501.97C745.733,471.822 745.733,422.869 715.585,392.721C702.356,379.491 380.066,58.201 366.836,44.972C353.638,31.774 336.836,24.354 319.586,22.707C305.002,21.315 93.263,0.703 81.113,0.097C60.067,-0.954 38.675,6.558 22.616,22.616C7.307,37.926 -0.233,58.083 0.005,78.166C0.158,90.957 21.834,301.853 22.429,315.577C23.238,334.217 30.753,352.617 44.972,366.836C64.714,386.578 372.979,695.844 392.721,715.585ZM221.206,462.624C199.538,440.957 109.62,350.947 109.62,350.947C95.375,336.702 95.375,315.292 109.62,301.047L301.047,109.62C315.292,95.375 336.702,95.375 350.947,109.62C350.947,109.62 557.592,316.079 616.139,374.813C679.714,438.589 568.691,438.77 585.773,495.797C588.986,506.52 600.846,531.699 594.432,548.233C579.351,587.118 529.349,575.43 521.799,548.233C515.39,525.148 528.92,514.925 524.759,499.813C517.88,474.829 491.657,481.134 483.903,499.813C458.989,559.836 503.029,591.37 493.423,628.195C479.788,680.463 410.137,673.342 400.675,628.195C392.608,589.708 425.265,574.286 421.93,520.583C419.956,488.804 394.552,464.882 377.567,488.023C360.792,510.879 402.256,542.428 373.64,575.065C341.566,611.644 283.344,579.898 301.047,528.499C311.597,497.869 326.263,466.649 311.901,462.624C282.374,454.351 267.942,509.361 221.206,462.624ZM180.995,84.554C205.968,109.528 205.968,150.079 180.995,175.052C156.022,200.026 115.471,200.026 90.497,175.052C65.524,150.079 65.524,109.528 90.497,84.554C115.471,59.581 156.022,59.581 180.995,84.554Z"/>
|
||||
<g transform="matrix(0.986683,0,0,0.986683,-136.081,-136.081)">
|
||||
<path d="M733.962,560.164C740.987,553.139 740.987,541.733 733.962,534.708L482.173,282.92C475.148,275.895 463.742,275.895 456.717,282.92L431.261,308.376C424.237,315.4 424.237,326.807 431.261,333.831L683.05,585.62C690.075,592.645 701.481,592.645 708.506,585.62L733.962,560.164ZM439.639,559.207C446.664,552.182 446.664,540.776 439.639,533.751L335.491,429.602C328.466,422.578 317.059,422.578 310.035,429.602L284.579,455.058C277.554,462.083 277.554,473.489 284.579,480.514L388.728,584.663C395.752,591.688 407.159,591.688 414.184,584.663L439.639,559.207ZM584.306,556.624C591.331,549.599 591.331,538.192 584.306,531.168L409.115,355.977C402.091,348.953 390.684,348.953 383.66,355.977L358.204,381.433C351.179,388.458 351.179,399.864 358.204,406.889L533.394,582.079C540.419,589.104 551.825,589.104 558.85,582.079L584.306,556.624ZM298.425,246.543C311.081,259.198 311.081,279.747 298.425,292.402C285.77,305.058 265.221,305.058 252.566,292.402C239.911,279.747 239.911,259.198 252.566,246.543C265.221,233.888 285.77,233.888 298.425,246.543Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
21
tagstudio/tests/qt/test_thumb_renderer.py
Normal file
21
tagstudio/tests/qt/test_thumb_renderer.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# Copyright (C) 2024 Travis Abendshien (CyanVoxel).
|
||||
# Licensed under the GPL-3.0 License.
|
||||
# Created for TagStudio: https://github.com/CyanVoxel/TagStudio
|
||||
|
||||
import io
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image
|
||||
from src.qt.widgets.thumb_renderer import ThumbRenderer
|
||||
from syrupy.extensions.image import PNGImageSnapshotExtension
|
||||
|
||||
|
||||
def test_svg_preview(cwd, snapshot):
|
||||
file_path: Path = cwd / "fixtures" / "sample.svg"
|
||||
renderer = ThumbRenderer()
|
||||
img: Image.Image = renderer._image_vector_thumb(file_path, 200)
|
||||
|
||||
img_bytes = io.BytesIO()
|
||||
img.save(img_bytes, format="PNG")
|
||||
img_bytes.seek(0)
|
||||
assert img_bytes.read() == snapshot(extension_class=PNGImageSnapshotExtension)
|
||||
Reference in New Issue
Block a user