根据新版本调整set_pattern:0~65535
This commit is contained in:
@@ -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 码值(0–65535)。"""
|
||||
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}%"
|
||||
)
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user