根据新版本调整set_pattern:0~65535

This commit is contained in:
xinzhu.yin
2026-07-07 18:59:44 +08:00
parent 9fa811a9eb
commit 32aaef1c0f
24 changed files with 3016 additions and 279 deletions

View File

@@ -22,6 +22,12 @@ from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from app.tests.color_accuracy import calculate_delta_e_2000
from app.solid_color_scale import (
SOLID_COLOR_MAX,
pct_to_solid_color,
solid_color_to_byte,
solid_color_to_pct,
)
from app.views.modern_styles import get_theme_palette
if TYPE_CHECKING:
@@ -41,10 +47,15 @@ DE_FORMULAS = ["2000", "94", "76"]
def _pct_to_gray_rgb(pct: int) -> tuple[int, int, int]:
value = int(round(pct * 255 / 100))
value = solid_color_to_byte(pct_to_solid_color(pct))
return value, value, value
def _pct_to_pattern_rgb(pct: int) -> int:
"""灰阶百分比 → SolidColor 码值065535"""
return pct_to_solid_color(pct)
def _rgb_to_hex(rgb: tuple[int, int, int]) -> str:
r, g, b = rgb
return f"#{r:02x}{g:02x}{b:02x}"
@@ -325,6 +336,8 @@ def create_calman_panel(self: "PQAutomationApp") -> None:
self.calman_stop_event = threading.Event()
self.calman_running = False
self.calman_patch_send_busy = False
self.calman_rgb_session = None
self.calman_rgb_session_test_type = None
self.calman_current_level = None
self.calman_last_record = None
self.calman_last_step_seconds = None
@@ -728,6 +741,29 @@ def toggle_calman_panel(self: "PQAutomationApp") -> None:
# ---------------------------------------------------------------------------
def _get_calman_rgb_session(self: "PQAutomationApp", test_type: str):
"""复用 Calman 发图 session避免每次点击都重新 stage profile。"""
cached = getattr(self, "calman_rgb_session", None)
if cached is not None and getattr(self, "calman_rgb_session_test_type", None) == test_type:
return cached
if not hasattr(self, "pattern_service") or self.pattern_service is None:
return None
session = self.pattern_service.prepare_session(
"rgb",
test_type=test_type,
log_details=False,
)
self.calman_rgb_session = session
self.calman_rgb_session_test_type = test_type
_calman_log(self, f"calman rgb session prepared test_type={test_type}")
return session
def _clear_calman_rgb_session(self: "PQAutomationApp") -> None:
self.calman_rgb_session = None
self.calman_rgb_session_test_type = None
def send_patch(self: "PQAutomationApp", pct: int) -> None:
"""点击色块时,发送对应灰阶图案到信号发生器。"""
if not self.signal_service.is_connected:
@@ -738,7 +774,7 @@ def send_patch(self: "PQAutomationApp", pct: int) -> None:
self.calman_status_var.set("发送进行中,请稍候...")
return
rgb_val = int(round(pct * 255 / 100))
rgb_val = _pct_to_pattern_rgb(pct)
self.calman_current_level = pct
self.calman_status_var.set(f"发送 {pct}%RGB={rgb_val}...")
_highlight_patch(self, pct)
@@ -751,8 +787,10 @@ def send_patch(self: "PQAutomationApp", pct: int) -> None:
_calman_log(self, f"send_solid_rgb start pct={pct}")
test_type = getattr(self.config, "current_test_type", "screen_module")
if hasattr(self, "pattern_service") and self.pattern_service is not None:
rgb_session = _get_calman_rgb_session(self, test_type)
self.pattern_service.send_rgb(
(rgb_val, rgb_val, rgb_val),
session=rgb_session,
test_type=test_type,
)
else:
@@ -902,11 +940,7 @@ def start_sequence_test(self: "PQAutomationApp") -> None:
test_type = getattr(self.config, "current_test_type", "screen_module")
rgb_session = None
if hasattr(self, "pattern_service") and self.pattern_service is not None:
rgb_session = self.pattern_service.prepare_session(
"rgb",
test_type=test_type,
log_details=False,
)
rgb_session = _get_calman_rgb_session(self, test_type)
_calman_log(self, f"sequence ucd profile applied test_type={test_type}")
order = sorted(self.calman_levels, reverse=True)
@@ -918,7 +952,7 @@ def start_sequence_test(self: "PQAutomationApp") -> None:
self._dispatch_ui(self.log_gui.log, "已停止连续测试", "warning")
break
step_t0 = time.perf_counter()
rgb_val = int(round(pct * 255 / 100))
rgb_val = _pct_to_pattern_rgb(pct)
self._dispatch_ui(
self.calman_status_var.set, f"[{i}/{total}] 发送 {pct}%"
)

View File

@@ -24,6 +24,12 @@ from typing import TYPE_CHECKING
import ttkbootstrap as ttk
from app.pq import pq_config
from app.solid_color_scale import (
SOLID_COLOR_MAX,
pct_to_solid_color,
solid_color_to_byte,
solid_color_to_pct,
)
if TYPE_CHECKING:
from pqAutomationApp import PQAutomationApp
@@ -56,19 +62,21 @@ def _gray_pct_of(rgb) -> str:
r = int(rgb[0])
except Exception:
return ""
return str(int(round(r / 255 * 100)))
return str(int(round(solid_color_to_pct(r))))
def _hex_of(rgb) -> str:
try:
r, g, b = int(rgb[0]), int(rgb[1]), int(rgb[2])
r = solid_color_to_byte(rgb[0])
g = solid_color_to_byte(rgb[1])
b = solid_color_to_byte(rgb[2])
except Exception:
return ""
return f"#{r:02X}{g:02X}{b:02X}"
def _luminance(rgb) -> float:
r, g, b = rgb
r, g, b = solid_color_to_byte(rgb[0]), solid_color_to_byte(rgb[1]), solid_color_to_byte(rgb[2])
return 0.2126 * r + 0.7152 * g + 0.0722 * b
@@ -99,7 +107,7 @@ def _gen_even(n: int) -> list[list[int]]:
out = []
for i in range(n):
pct = 100.0 - (100.0 / (n - 1)) * i
v = int(round(pct / 100.0 * 255))
v = pct_to_solid_color(pct)
out.append([v, v, v])
return out
@@ -118,7 +126,7 @@ def _gen_pq(n: int) -> list[list[int]]:
else:
Lm1 = L ** m1
v_pq = ((c1 + c2 * Lm1) / (1.0 + c3 * Lm1)) ** m2
v = int(round(max(0.0, min(1.0, v_pq)) * 255))
v = int(round(max(0.0, min(1.0, v_pq)) * SOLID_COLOR_MAX))
out.append([v, v, v])
return out
@@ -129,7 +137,7 @@ def _gen_gamma(n: int, gamma: float = 2.2) -> list[list[int]]:
out = []
for i in range(n):
lin = 1.0 - i / (n - 1)
v = int(round((lin ** (1.0 / gamma)) * 255))
v = int(round((lin ** (1.0 / gamma)) * SOLID_COLOR_MAX))
out.append([v, v, v])
return out
@@ -761,8 +769,8 @@ def _parse_rgb_from_form(self: "PQAutomationApp"):
except ValueError:
messagebox.showerror("输入错误", "R/G/B 必须为整数")
return None
if not all(0 <= v <= 255 for v in (r, g, b)):
messagebox.showerror("输入错误", "R/G/B 必须在 0~255 范围内")
if not all(0 <= v <= SOLID_COLOR_MAX for v in (r, g, b)):
messagebox.showerror("输入错误", f"R/G/B 必须在 0~{SOLID_COLOR_MAX} 范围内")
return None
return [r, g, b]
@@ -775,7 +783,7 @@ def _fill_rgb_from_pct(self: "PQAutomationApp"):
messagebox.showerror("输入错误", "灰度 % 必须为数字")
return
pct = max(0.0, min(100.0, pct))
v = int(round(pct / 100.0 * 255))
v = pct_to_solid_color(pct)
self._gamma_edit_r_var.set(str(v))
self._gamma_edit_g_var.set(str(v))
self._gamma_edit_b_var.set(str(v))
@@ -904,7 +912,7 @@ def _paste_from_clipboard(self: "PQAutomationApp"):
if s.endswith("%"):
try:
pct = float(s.rstrip("%"))
v = int(round(max(0, min(100, pct)) / 100.0 * 255))
v = pct_to_solid_color(max(0, min(100, pct)))
rows.append([v, v, v])
continue
except ValueError:
@@ -914,7 +922,7 @@ def _paste_from_clipboard(self: "PQAutomationApp"):
if len(parts) == 1:
try:
v = int(parts[0])
if 0 <= v <= 255:
if 0 <= v <= SOLID_COLOR_MAX:
rows.append([v, v, v])
continue
except ValueError:
@@ -929,7 +937,7 @@ def _paste_from_clipboard(self: "PQAutomationApp"):
except ValueError:
errors.append(f"{ln_no} 行非整数:{s}")
continue
if not all(0 <= v <= 255 for v in (r, g, b)):
if not all(0 <= v <= SOLID_COLOR_MAX for v in (r, g, b)):
errors.append(f"{ln_no} 行越界:{s}")
continue
rows.append([r, g, b])
@@ -980,7 +988,7 @@ def _run_validation(self: "PQAutomationApp"):
bad = [
i for i, rgb in enumerate(params)
if not all(0 <= int(v) <= 255 for v in rgb)
if not all(0 <= int(v) <= SOLID_COLOR_MAX for v in rgb)
]
if bad:
msgs.append(f"⚠ 越界点 (索引): {bad}")

View File

@@ -9,9 +9,14 @@ import threading
import tkinter as tk
from tkinter import filedialog, messagebox
from typing import TYPE_CHECKING
import ttkbootstrap as ttk
from typing import TYPE_CHECKING
from app.solid_color_scale import (
SOLID_COLOR_MAX,
byte_to_solid_color,
)
if TYPE_CHECKING:
from pqAutomationApp import PQAutomationApp
@@ -196,8 +201,12 @@ def _load_patterns(self: "PQAutomationApp"):
continue
if r is None or g is None or b is None:
continue
if min(r, g, b) < 0 or max(r, g, b) > 255:
if min(r, g, b) < 0 or max(r, g, b) > SOLID_COLOR_MAX:
continue
if max(r, g, b) <= 255:
r = byte_to_solid_color(r)
g = byte_to_solid_color(g)
b = byte_to_solid_color(b)
patterns.append((r, g, b))
finally:
wb.close()