mirror of
https://github.com/esphome/esphome.git
synced 2026-01-08 19:20:51 -07:00
[image] Replace use of cairosvg with resvg-py (#12863)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -374,23 +374,6 @@ def is_svg_file(file):
|
|||||||
return "<svg" in str(f.read(1024))
|
return "<svg" in str(f.read(1024))
|
||||||
|
|
||||||
|
|
||||||
def validate_cairosvg_installed():
|
|
||||||
try:
|
|
||||||
import cairosvg
|
|
||||||
except ImportError as err:
|
|
||||||
raise cv.Invalid(
|
|
||||||
"Please install the cairosvg python package to use this feature. "
|
|
||||||
"(pip install cairosvg)"
|
|
||||||
) from err
|
|
||||||
|
|
||||||
major, minor, _ = cairosvg.__version__.split(".")
|
|
||||||
if major < "2" or major == "2" and minor < "2":
|
|
||||||
raise cv.Invalid(
|
|
||||||
"Please update your cairosvg installation to at least 2.2.0. "
|
|
||||||
"(pip install -U cairosvg)"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def validate_file_shorthand(value):
|
def validate_file_shorthand(value):
|
||||||
value = cv.string_strict(value)
|
value = cv.string_strict(value)
|
||||||
parts = value.strip().split(":")
|
parts = value.strip().split(":")
|
||||||
@@ -490,9 +473,7 @@ def validate_settings(value, path=()):
|
|||||||
)
|
)
|
||||||
if file := value.get(CONF_FILE):
|
if file := value.get(CONF_FILE):
|
||||||
file = Path(file)
|
file = Path(file)
|
||||||
if is_svg_file(file):
|
if not is_svg_file(file):
|
||||||
validate_cairosvg_installed()
|
|
||||||
else:
|
|
||||||
try:
|
try:
|
||||||
Image.open(file)
|
Image.open(file)
|
||||||
except UnidentifiedImageError as exc:
|
except UnidentifiedImageError as exc:
|
||||||
@@ -669,44 +650,35 @@ async def write_image(config, all_frames=False):
|
|||||||
raise core.EsphomeError(f"Could not load image file {path}")
|
raise core.EsphomeError(f"Could not load image file {path}")
|
||||||
|
|
||||||
resize = config.get(CONF_RESIZE)
|
resize = config.get(CONF_RESIZE)
|
||||||
if is_svg_file(path):
|
try:
|
||||||
# Local import so use of non-SVG files needn't require cairosvg installed
|
if is_svg_file(path):
|
||||||
from pyexpat import ExpatError
|
import resvg_py
|
||||||
from xml.etree.ElementTree import ParseError
|
|
||||||
|
|
||||||
from cairosvg import svg2png
|
if resize:
|
||||||
from cairosvg.helpers import PointError
|
width, height = resize
|
||||||
|
# resvg-py allows rendering by width/height directly
|
||||||
if not resize:
|
image_data = resvg_py.svg_to_bytes(
|
||||||
resize = (None, None)
|
svg_path=str(path), width=int(width), height=int(height)
|
||||||
try:
|
|
||||||
with open(path, "rb") as file:
|
|
||||||
image = svg2png(
|
|
||||||
file_obj=file,
|
|
||||||
output_width=resize[0],
|
|
||||||
output_height=resize[1],
|
|
||||||
)
|
)
|
||||||
image = Image.open(io.BytesIO(image))
|
else:
|
||||||
|
# Default size
|
||||||
|
image_data = resvg_py.svg_to_bytes(svg_path=str(path))
|
||||||
|
|
||||||
|
# Convert bytes to Pillow Image
|
||||||
|
image = Image.open(io.BytesIO(image_data))
|
||||||
width, height = image.size
|
width, height = image.size
|
||||||
except (
|
|
||||||
ValueError,
|
else:
|
||||||
ParseError,
|
image = Image.open(path)
|
||||||
IndexError,
|
width, height = image.size
|
||||||
ExpatError,
|
if resize:
|
||||||
AttributeError,
|
# Preserve aspect ratio
|
||||||
TypeError,
|
new_width_max = min(width, resize[0])
|
||||||
PointError,
|
new_height_max = min(height, resize[1])
|
||||||
) as e:
|
ratio = min(new_width_max / width, new_height_max / height)
|
||||||
raise core.EsphomeError(f"Could not load SVG image {path}: {e}") from e
|
width, height = int(width * ratio), int(height * ratio)
|
||||||
else:
|
except (OSError, UnidentifiedImageError, ValueError) as exc:
|
||||||
image = Image.open(path)
|
raise core.EsphomeError(f"Could not read image file {path}: {exc}") from exc
|
||||||
width, height = image.size
|
|
||||||
if resize:
|
|
||||||
# Preserve aspect ratio
|
|
||||||
new_width_max = min(width, resize[0])
|
|
||||||
new_height_max = min(height, resize[1])
|
|
||||||
ratio = min(new_width_max / width, new_height_max / height)
|
|
||||||
width, height = int(width * ratio), int(height * ratio)
|
|
||||||
|
|
||||||
if not resize and (width > 500 or height > 500):
|
if not resize and (width > 500 or height > 500):
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
|
|||||||
@@ -19,13 +19,7 @@ ruamel.yaml==0.19.1 # dashboard_import
|
|||||||
ruamel.yaml.clib==0.2.15 # dashboard_import
|
ruamel.yaml.clib==0.2.15 # dashboard_import
|
||||||
esphome-glyphsets==0.2.0
|
esphome-glyphsets==0.2.0
|
||||||
pillow==11.3.0
|
pillow==11.3.0
|
||||||
|
resvg-py==0.2.5
|
||||||
# pycairo fork for Windows
|
|
||||||
cairosvg @ git+https://github.com/clydebarrow/cairosvg.git@release ; sys_platform == 'win32'
|
|
||||||
|
|
||||||
# Original for everything else
|
|
||||||
cairosvg==2.8.2 ; sys_platform != 'win32'
|
|
||||||
|
|
||||||
freetype-py==2.5.1
|
freetype-py==2.5.1
|
||||||
jinja2==3.1.6
|
jinja2==3.1.6
|
||||||
bleak==2.1.1
|
bleak==2.1.1
|
||||||
|
|||||||
Reference in New Issue
Block a user