NaraMotion / examples /06_composite_ops.py
ArifiIslam's picture
Release NaraMotion v0.26.0: Structure of Arrays (SoA), Path Arena Allocator, Uniform Grid Indexing, Dual-Buffer Rendering & Centroid Spring Pop-in
b516e00 verified
Raw History Blame Contribute Delete
1.75 kB
"""
NaraMotion Example 06: Composition and Blending Modes
"""
import os
from naramotion import Image, Context, Format, CompOp, Font
def get_font():
for p in ["C:\\Windows\\Fonts\\segoeui.ttf", "C:\\Windows\\Fonts\\arial.ttf"]:
if os.path.exists(p):
return p
return None
def main():
width, height = 900, 600
img = Image(width, height, Format.PRGB32)
modes = [
("SrcOver", CompOp.SRC_OVER),
("Difference", CompOp.DIFFERENCE),
("Multiply", CompOp.MULTIPLY),
("Screen", CompOp.SCREEN),
("Overlay", CompOp.OVERLAY),
("Xor", CompOp.XOR),
]
with Context(img) as ctx:
ctx.fill_all("#18181B")
font_path = get_font()
font = Font.from_file(font_path, 18.0) if font_path else None
cols = 3
cell_w, cell_h = 280, 260
margin_x, margin_y = 30, 20
for idx, (name, op) in enumerate(modes):
r = idx // cols
c = idx % cols
ox = margin_x + c * cell_w
oy = margin_y + r * cell_h
# Label
if font:
ctx.fill_text(ox + 20, oy + 30, font, name, "#E4E4E7")
# Draw overlapping blending circles
with ctx.push_state():
ctx.comp_op = op
ctx.fill_circle(ox + 80, oy + 120, 50, "#EF4444CC")
ctx.fill_circle(ox + 130, oy + 120, 50, "#10B981CC")
ctx.fill_circle(ox + 105, oy + 170, 50, "#3B82F6CC")
os.makedirs("output", exist_ok=True)
out_file = "output/06_composite_ops.png"
img.write_to_file(out_file)
print(f"Saved: {out_file}")
if __name__ == "__main__":
main()