接口开始5%
This commit is contained in:
@@ -15,9 +15,14 @@ def _outer_ring_pixels(image: Image.Image, thickness: int):
|
||||
yield image.getpixel((x, y))
|
||||
|
||||
|
||||
def analyze_asset(path: Path, spec: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Analyze one PNG against its manifest v2 specification."""
|
||||
path = Path(path)
|
||||
def analyze_asset(path: Path, spec: dict[str, Any], workspace: Path) -> dict[str, Any]:
|
||||
"""按 schema v3 物理规格分析单张 PNG,并只输出工作区相对路径。"""
|
||||
workspace = Path(workspace).resolve()
|
||||
path = Path(path).resolve()
|
||||
try:
|
||||
report_path = path.relative_to(workspace).as_posix()
|
||||
except ValueError as error:
|
||||
raise ValueError(f"asset path escapes workspace: {path}") from error
|
||||
errors: list[str] = []
|
||||
warnings: list[str] = []
|
||||
metrics: dict[str, int] = {}
|
||||
@@ -40,14 +45,34 @@ def analyze_asset(path: Path, spec: dict[str, Any]) -> dict[str, Any]:
|
||||
errors.append(f"alpha-required asset has no alpha channel or transparency table, got {mode}")
|
||||
|
||||
padding = int(alpha.get("transparentOuterPadding", 0))
|
||||
max_alpha = int(alpha.get("cornerMaxAlpha", 0))
|
||||
opaque_padding = sum(1 for pixel in _outer_ring_pixels(image, padding) if pixel[3] > max_alpha)
|
||||
max_alpha = int(alpha.get("cornerMaxAlpha", 255))
|
||||
corners = (
|
||||
image.getpixel((0, 0))[3],
|
||||
image.getpixel((width - 1, 0))[3],
|
||||
image.getpixel((0, height - 1))[3],
|
||||
image.getpixel((width - 1, height - 1))[3],
|
||||
)
|
||||
corner_violations = sum(1 for value in corners if value > max_alpha)
|
||||
metrics["cornerAlphaViolations"] = corner_violations
|
||||
if corner_violations:
|
||||
errors.append(f"corners contain {corner_violations} pixels above alpha {max_alpha}")
|
||||
|
||||
# 不透明长背景没有边缘/透明度扫描需求;避免无意义地把每张 1440×3600 图
|
||||
# 展开成数百万个 Python 元组。透明资产仍完整执行原有像素级质量合同。
|
||||
opaque_padding = 0
|
||||
if padding > 0:
|
||||
opaque_padding = sum(1 for pixel in _outer_ring_pixels(image, padding) if pixel[3] > max_alpha)
|
||||
metrics["outerPaddingViolations"] = opaque_padding
|
||||
if opaque_padding:
|
||||
errors.append(f"outer padding contains {opaque_padding} pixels above alpha {max_alpha}")
|
||||
|
||||
edge = spec.get("edge", {})
|
||||
pixels = list(image.get_flattened_data())
|
||||
needs_edge_pixels = any(edge.get(field) for field in (
|
||||
"forbidChromaResidue",
|
||||
"forbidLightFringe",
|
||||
"premultipliedAlphaCheck",
|
||||
))
|
||||
pixels = list(image.get_flattened_data()) if needs_edge_pixels else []
|
||||
|
||||
chroma_residue = sum(
|
||||
1
|
||||
@@ -83,11 +108,15 @@ def analyze_asset(path: Path, spec: dict[str, Any]) -> dict[str, Any]:
|
||||
|
||||
expected_color_space = spec.get("quality", {}).get("colorSpace")
|
||||
if expected_color_space == "sRGB" and not ("srgb" in info or "icc_profile" in info):
|
||||
warnings.append("PNG does not declare an sRGB chunk or ICC profile")
|
||||
errors.append("PNG does not declare an sRGB chunk or ICC profile")
|
||||
|
||||
expected_mode = spec.get("processing", {}).get("outputMode")
|
||||
if expected_mode and mode != expected_mode:
|
||||
errors.append(f"output mode expected {expected_mode}, got {mode}")
|
||||
|
||||
return {
|
||||
"id": spec.get("id", path.stem),
|
||||
"path": str(path),
|
||||
"path": report_path,
|
||||
"width": width,
|
||||
"height": height,
|
||||
"mode": mode,
|
||||
|
||||
Reference in New Issue
Block a user