image.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. """An image component."""
  2. from __future__ import annotations
  3. import base64
  4. import io
  5. from typing import Any, Optional, Union
  6. from reflex.components.component import Component
  7. from reflex.components.libs.chakra import ChakraComponent, LiteralImageLoading
  8. from reflex.utils.serializers import serializer
  9. from reflex.vars import Var
  10. class Image(ChakraComponent):
  11. """Display an image."""
  12. tag = "Image"
  13. # How to align the image within its bounds. It maps to css `object-position` property.
  14. align: Var[str]
  15. # Fallback Reflex component to show if image is loading or image fails.
  16. fallback: Optional[Component] = None
  17. # Fallback image src to show if image is loading or image fails.
  18. fallback_src: Var[str]
  19. # How the image to fit within its bounds. It maps to css `object-fit` property.
  20. fit: Var[str]
  21. # The native HTML height attribute to the passed to the img.
  22. html_height: Var[str]
  23. # The native HTML width attribute to the passed to the img.
  24. html_width: Var[str]
  25. # If true, opt out of the fallbackSrc logic and use as img.
  26. ignore_fallback: Var[bool]
  27. # "eager" | "lazy"
  28. loading: Var[LiteralImageLoading]
  29. # The path/url to the image or PIL image object.
  30. src: Var[Any]
  31. # The alt text of the image.
  32. alt: Var[str]
  33. # Provide multiple sources for an image, allowing the browser
  34. # to select the most appropriate source based on factors like
  35. # screen resolution and device capabilities.
  36. # Learn more _[here](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images)_
  37. src_set: Var[str]
  38. def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
  39. """Get the event triggers for the component.
  40. Returns:
  41. The event triggers.
  42. """
  43. return {
  44. **super().get_event_triggers(),
  45. "on_error": lambda: [],
  46. "on_load": lambda: [],
  47. }
  48. @classmethod
  49. def create(cls, *children, **props) -> Component:
  50. """Create an Image component.
  51. Args:
  52. *children: The children of the image.
  53. **props: The props of the image.
  54. Returns:
  55. The Image component.
  56. """
  57. src = props.get("src", None)
  58. if src is not None and not isinstance(src, (Var)):
  59. props["src"] = Var.create(value=src, _var_is_string=True)
  60. return super().create(*children, **props)
  61. try:
  62. from PIL.Image import Image as Img
  63. @serializer
  64. def serialize_image(image: Img) -> str:
  65. """Serialize a plotly figure.
  66. Args:
  67. image: The image to serialize.
  68. Returns:
  69. The serialized image.
  70. """
  71. buff = io.BytesIO()
  72. image.save(buff, format="PNG")
  73. image_bytes = buff.getvalue()
  74. base64_image = base64.b64encode(image_bytes).decode("utf-8")
  75. return f"data:image/png;base64,{base64_image}"
  76. except ImportError:
  77. pass