classes.c52_raster_logo

 1import drawBot
 2from lib import color
 3from .c50_image_pipeline import KImagePipeline
 4
 5
 6class KRasterLogo:
 7    """Project-wide logo renderer powered by ``KImagePipeline``."""
 8
 9    def __init__(self, pipeline: KImagePipeline):
10        self.pipeline = pipeline
11
12    @property
13    def image(self) -> drawBot.ImageObject:
14        """Return the underlying upsampled image object."""
15        return self.pipeline._requireImage()
16
17    def size(self) -> tuple[float, float]:
18        """Return rendered image dimensions (upsampled)."""
19        return self.image.size()
20
21    def draw(self, position: tuple[float, float], compensateOffset: bool = True):
22        """Draw with fidelity-aware scaling through ``KImagePipeline.draw()``."""
23        self.pipeline.draw(position=position, compensateOffset=compensateOffset)
24        return self
25
26    @classmethod
27    def create(
28        cls,
29        size: float = 200,
30        lineCount: float = 7,
31        sharpness: float = 0.95,
32        shade: tuple | color.HSL | color.CMYK = (0, 0, 0),
33        darkness: float = 0.5,
34        fidelity: float = KImagePipeline.ULTRA_HIGH_RES,
35    ) -> "KRasterLogo":
36        """Create the KOMETA logo image.
37
38        Args:
39            size: Output logo width and height in points.
40            lineCount: Number of lines in the line screen.
41            sharpness: Line screen sharpness.
42            shade: Target shade for non-transparent pixels.
43            darkness: Radial gradient center darkness, where larger values darken.
44            fidelity: Fidelity multiplier used during rendering.
45
46        Returns:
47            ``KRasterLogo`` with a rendered pipeline ready for ``draw()``.
48        """
49        if fidelity <= 0:
50            raise ValueError("fidelity must be greater than 0")
51
52        pipeline = KImagePipeline(size=(size, size), fidelity=fidelity)
53
54        with pipeline.canvas() as ctx:
55            w, h = ctx.dimensions
56            center = (w / 2, h / 2)
57            drawBot.radialGradient(
58                center,
59                center,
60                colors=[(1 - darkness,) * 3, (1,) * 3],
61                locations=[0, 1],
62                startRadius=w / 4,
63                endRadius=w / 2,
64            )
65            drawBot.rect(*ctx.coords)
66
67        lineWidth = size / lineCount
68        pipeline.lineScreen(width=lineWidth, sharpness=sharpness)
69        image = pipeline._requireImage()
70        image.falseColor(color.toRGBAFloat(shade), (0,) * 4)
71
72        return cls(pipeline)