初始化奇妙小屏幕控制器项目
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
from .text_renderer import TextOptions, render_text
|
||||
|
||||
DIAGNOSTIC_MODES = {
|
||||
"corners_lines",
|
||||
"row_bands",
|
||||
"address_check",
|
||||
"address_bit_0",
|
||||
"address_bit_1",
|
||||
"address_bit_2",
|
||||
"address_bit_3",
|
||||
"address_bit_4",
|
||||
"text_ok123",
|
||||
"clear",
|
||||
}
|
||||
|
||||
|
||||
def render_diagnostic(mode: str, size: tuple[int, int] = (64, 64)) -> Image.Image:
|
||||
if mode not in DIAGNOSTIC_MODES:
|
||||
allowed = ", ".join(sorted(DIAGNOSTIC_MODES))
|
||||
raise ValueError(f"diagnostic mode must be one of: {allowed}")
|
||||
|
||||
if mode == "clear":
|
||||
return Image.new("RGB", size, (0, 0, 0))
|
||||
if mode == "corners_lines":
|
||||
return _render_corners_lines(size)
|
||||
if mode == "row_bands":
|
||||
return _render_row_bands(size)
|
||||
if mode == "address_check":
|
||||
return _render_address_check(size)
|
||||
if mode.startswith("address_bit_"):
|
||||
return _render_address_bit(int(mode.rsplit("_", 1)[1]), size)
|
||||
return render_text(TextOptions(text="OK123", size=12, x=4, y=24), size=size)
|
||||
|
||||
|
||||
def _render_corners_lines(size: tuple[int, int]) -> Image.Image:
|
||||
width, height = size
|
||||
image = Image.new("RGB", size, (0, 0, 0))
|
||||
draw = ImageDraw.Draw(image)
|
||||
|
||||
for y, color in ((0, (80, 80, 80)), (31, (255, 180, 0)), (32, (0, 180, 255)), (63, (80, 80, 80))):
|
||||
if y < height:
|
||||
draw.line((0, y, width - 1, y), fill=color)
|
||||
for x in (0, width - 1):
|
||||
draw.line((x, 0, x, height - 1), fill=(80, 80, 80))
|
||||
|
||||
marker = 4
|
||||
draw.rectangle((0, 0, marker, marker), fill=(255, 0, 0))
|
||||
draw.rectangle((width - marker - 1, 0, width - 1, marker), fill=(0, 255, 0))
|
||||
draw.rectangle((0, height - marker - 1, marker, height - 1), fill=(0, 0, 255))
|
||||
draw.rectangle((width - marker - 1, height - marker - 1, width - 1, height - 1), fill=(255, 255, 255))
|
||||
return image
|
||||
|
||||
|
||||
def _render_row_bands(size: tuple[int, int]) -> Image.Image:
|
||||
width, height = size
|
||||
image = Image.new("RGB", size, (0, 0, 0))
|
||||
draw = ImageDraw.Draw(image)
|
||||
colors = (
|
||||
(255, 0, 0),
|
||||
(255, 120, 0),
|
||||
(255, 255, 0),
|
||||
(0, 255, 0),
|
||||
(0, 255, 255),
|
||||
(0, 0, 255),
|
||||
(180, 0, 255),
|
||||
(255, 255, 255),
|
||||
)
|
||||
|
||||
band_height = max(1, height // len(colors))
|
||||
for index, color in enumerate(colors):
|
||||
y0 = index * band_height
|
||||
y1 = height - 1 if index == len(colors) - 1 else min(height - 1, y0 + band_height - 1)
|
||||
draw.rectangle((0, y0, width - 1, y1), fill=color)
|
||||
draw.line((0, y0, width - 1, y0), fill=(0, 0, 0))
|
||||
return image
|
||||
|
||||
|
||||
def _render_address_check(size: tuple[int, int]) -> Image.Image:
|
||||
width, height = size
|
||||
image = Image.new("RGB", size, (0, 0, 0))
|
||||
draw = ImageDraw.Draw(image)
|
||||
|
||||
bit_colors = (
|
||||
(255, 0, 0),
|
||||
(0, 255, 0),
|
||||
(0, 0, 255),
|
||||
(255, 255, 0),
|
||||
(255, 0, 255),
|
||||
)
|
||||
segment_width = max(1, width // len(bit_colors))
|
||||
|
||||
for y in range(height):
|
||||
for bit, color in enumerate(bit_colors):
|
||||
if y & (1 << bit):
|
||||
x0 = bit * segment_width
|
||||
x1 = width - 1 if bit == len(bit_colors) - 1 else min(width - 1, x0 + segment_width - 2)
|
||||
draw.line((x0, y, x1, y), fill=color)
|
||||
|
||||
diagonal_x = min(width - 1, y)
|
||||
draw.point((diagonal_x, y), fill=(255, 255, 255))
|
||||
draw.point((width - 1 - diagonal_x, y), fill=(80, 80, 80))
|
||||
|
||||
for y in (0, 31, 32, 63):
|
||||
if y < height:
|
||||
draw.line((0, y, width - 1, y), fill=(255, 255, 255))
|
||||
return image
|
||||
|
||||
|
||||
def _render_address_bit(bit: int, size: tuple[int, int]) -> Image.Image:
|
||||
width, height = size
|
||||
image = Image.new("RGB", size, (0, 0, 0))
|
||||
draw = ImageDraw.Draw(image)
|
||||
colors = (
|
||||
(255, 0, 0),
|
||||
(0, 255, 0),
|
||||
(0, 0, 255),
|
||||
(255, 255, 0),
|
||||
(255, 0, 255),
|
||||
)
|
||||
color = colors[bit]
|
||||
|
||||
for y in range(height):
|
||||
if y & (1 << bit):
|
||||
draw.line((0, y, width - 1, y), fill=color)
|
||||
|
||||
for y in (0, 31, 32, 63):
|
||||
if y < height:
|
||||
draw.line((0, y, width - 1, y), fill=(255, 255, 255))
|
||||
return image
|
||||
Reference in New Issue
Block a user