compare-screenshots

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Compare Screenshots

对比截图

Decide which image is less wrong against what the scene should show — not whether the candidate matches the baseline. The baseline is just an earlier attempt; it can be wrong too. Treat both images as candidates measured against a target you establish yourself. Metrics locate where the images differ; they never decide who is right.
判断哪张图片更接近场景应呈现的效果(即错误更少)——而非判断候选图是否与基准图匹配。基准图只是早期尝试的结果,它本身也可能存在错误。将两张图都视为候选对象,以你自行确立的目标作为评判标准。指标仅用于定位图片差异,绝不决定孰是孰非。

Workflow

工作流程

  1. Establish the target from first principles. Before looking at distance, decide what this image should show: the visual requirement, the design intent, what the thing depicts in reality, and any domain skill that owns the look. This — not the baseline — is ground truth. Write it down in one or two concrete sentences ("low sun should cast long shadows east; trees fill the canopy; labels stay legible at this zoom").
    • If the right answer isn't clear — competing valid readings, a taste or product-intent call, a tradeoff only the owner can settle — stop and ask the user what the correct answer should be. Show them the comparison. Do not quietly default to the baseline to avoid asking; that bakes in whatever the baseline got wrong.
  2. Confirm comparability so the differences you see are real, not capture artifacts: same viewport, DPR, route/page, frozen time/tick, camera intent, UI state, data, fonts/assets where they matter. If not comparable, fix capture setup or compare only a crop/feature where the mismatch is harmless.
  3. Generate artifacts to locate divergence, sized to the question: side-by-side, key-feature crops/zooms, grayscale, absolute grayscale heatmap, pixelmatch diff, per-image Sobel/edge maps, edge-difference heatmap, JSON metrics.
  4. Judge each divergence against the target. For every place the two images differ, name what is actually there in plain terms — missing content, wrong camera, bad hierarchy, weak contrast, wrong depth, text overlap, layout shift, clipped edge, unexpected blur, style mismatch — and decide which side is closer to correct. The answer can be the candidate, the baseline, both wrong, or a genuine toss-up.
  5. Get a neutral second opinion for disputed or high-stakes calls: a fresh subagent given only the two images and neutral labels, per
    references/subagent-visual-review.md
    .
  6. Conclude with one verdict: candidate is less wrong (accept, and re-bless the baseline if one exists), baseline is less wrong (reject), both wrong (another pass needed — say what's still off), or unclear (ask the user). Never accept on a lower score alone or reject on a higher one. Never hide content, blur detail, crop away differences, or make the capture less truthful to move a number.
  1. 从基本原则出发确立目标。在查看差异度之前,先明确这张图片应该呈现什么:视觉要求、设计意图、事物的实际呈现效果,以及任何主导视觉风格的领域技能。这才是真实标准,而非基准图。用一两句具体的话写下来(例如“低角度阳光应朝东投射长阴影;树木需填满树冠;此缩放级别下标签应保持清晰可读”)。
    • 如果正确答案不明确——存在相互矛盾的合理解读、涉及品味或产品意图的决策、只有所有者才能解决的权衡问题——请立即询问用户正确答案是什么。向他们展示对比结果。切勿为了避免询问而默认以基准图为准,否则会将基准图的错误固化下来。
  2. 确认可比性,确保你看到的差异是真实存在的,而非截图 artifacts:相同视口、设备像素比(DPR)、路由/页面、冻结时间/帧、相机意图、UI状态、数据、关键字体/资源。如果不具备可比性,请修正截图设置,或仅对比裁剪区域/特定功能(该区域的不匹配无不良影响)。
  3. 生成用于定位差异的工件,根据问题调整工件规模:并排对比图、关键功能裁剪/放大图、灰度图、绝对灰度热力图、pixelmatch差异图、单图Sobel/边缘图、边缘差异热力图、JSON指标。
  4. 根据目标评判每一处差异。对于两张图片的每一处差异,用直白的语言描述实际情况——内容缺失、相机角度错误、层级混乱、对比度不足、深度错误、文本重叠、布局偏移、边缘裁剪、意外模糊、风格不匹配——然后判断哪一方更接近正确。答案可能是候选图、基准图、两者都错,或确实难以抉择。
  5. 针对有争议或高风险的判断获取中立的二次意见:让新的子代理仅查看两张图片和中立标签,具体参考
    references/subagent-visual-review.md
  6. 得出明确结论:候选图错误更少(接受,若存在基准图则重新确认其有效性)、基准图错误更少(拒绝)、两者都错(需要重新处理——说明仍存在的问题),或无法判断(询问用户)。绝不能仅因分数较低就接受,或因分数较高就拒绝。绝不能隐藏内容、模糊细节、裁剪差异区域,或为了改变分数而让截图失真。

Useful Metrics

实用指标

Pick metrics that answer the question. For full visual comparisons, report:
  • mae
    : mean absolute grayscale difference, 0..255, lower is closer.
  • rmse
    : grayscale root mean square error, lower is closer.
  • diffRatio16
    ,
    diffRatio32
    ,
    diffRatio64
    : fraction of pixels over each grayscale delta threshold.
  • pixelmatchRatio
    : mismatch ratio from pixelmatch over grayscale images.
  • edgeEnergyCurrent
    and
    edgeEnergyCandidate
    : average Sobel edge strength.
  • edgeEnergyRatio
    : candidate/current. Far below 1 usually means missing geometry, props, labels, or terrain; far above 1 usually means noisy or incorrect detail.
  • edgeDiffRatio32
    : fraction of pixels whose Sobel edge differs materially.
  • avgLuminanceCurrent
    ,
    avgLuminanceCandidate
    ,
    avgLuminanceDelta
    : average brightness and delta. Use when a render is visibly too dark/light even if a broader distance score improves.
  • Content proxies relevant to the scene: black/void ratio, terrain-like ratio, water-like ratio, team-color ratio, label/text mask ratio.
For UI/document/layout reviews, also use crop bounds, text/foreground mask coverage, contrast checks, edge clipping, element positions, and before/after dimensions when those beat global pixel distance.
选择能解答问题的指标。对于完整视觉对比,需报告:
  • mae
    :灰度平均绝对差,范围0..255,数值越小越接近。
  • rmse
    :灰度均方根误差,数值越小越接近。
  • diffRatio16
    diffRatio32
    diffRatio64
    :超过各灰度差值阈值的像素占比。
  • pixelmatchRatio
    :灰度图经pixelmatch计算得到的不匹配占比。
  • edgeEnergyCurrent
    edgeEnergyCandidate
    :平均Sobel边缘强度。
  • edgeEnergyRatio
    :候选图/当前图的比值。远小于1通常意味着缺失几何形状、道具、标签或地形;远大于1通常意味着存在噪点或错误细节。
  • edgeDiffRatio32
    :Sobel边缘存在实质性差异的像素占比。
  • avgLuminanceCurrent
    avgLuminanceCandidate
    avgLuminanceDelta
    :平均亮度及亮度差值。当渲染图明显过暗/过亮时使用,即使整体差异分数有所改善也需关注。
  • 与场景相关的内容代理指标:黑色/空白区域占比、类地形区域占比、类水域区域占比、团队颜色区域占比、标签/文本蒙版占比。
对于UI/文档/布局审阅,还可使用裁剪边界、文本/前景蒙版覆盖率、对比度检查、边缘裁剪、元素位置及前后尺寸,当这些指标优于全局像素差异时优先使用。

Distance Score

差异分数

When a single fixed-pair number is useful, this default works for structural changes:
distance = 0.35 * diffRatio32 + 0.25 * pixelmatchRatio + 0.25 * edgeDiffRatio32 + 0.15 * min(1, abs(log2(edgeEnergyRatio)))
It measures distance from the other image, nothing more. Because the baseline can be wrong, a distance of 0 is not success and a large distance is not failure — a richer scene, clearer models, stronger labels, real depth, or better lighting all legitimately raise it. Use the score to find where the images move; decide who is right in step 4. Name the field for what it measures (distance, not "parity") so no one reads it as a verdict.
Report the full-frame score and, when UI dominates the shot, a labeled world-crop score. Use the world-crop score to locate renderer movement and keep the full-frame score so UI/camera mistakes stay visible.
当需要一个固定的配对数值时,以下默认公式适用于结构性变化:
distance = 0.35 * diffRatio32 + 0.25 * pixelmatchRatio + 0.25 * edgeDiffRatio32 + 0.15 * min(1, abs(log2(edgeEnergyRatio)))
该分数仅用于衡量与另一张图的差异度,别无其他含义。由于基准图可能存在错误,差异度为0不代表成功,差异度大也不代表失败——更丰富的场景、更清晰的模型、更醒目的标签、真实的深度或更好的光照都可能合理地提高分数。使用分数来定位图片的变化点;在步骤4中判断孰是孰非。为该字段命名时需体现其测量内容(即差异度,而非“一致性”),避免被误读为最终结论。
报告全帧分数,当UI在画面中占主导时,同时报告带标签的世界区域裁剪分数。使用世界区域裁剪分数定位渲染器的移动,保留全帧分数以便UI/相机错误可见。

Score Discipline

分数使用规范

  • Quote the previous and new distance for the same pair each iteration, then say whether the movement is toward the target, away from it, or diagnostic noise.
  • Prefer edge metrics for missing-content bugs. A flat top-down map can show a deceptively moderate grayscale diff while edge energy proves trees, roads, city forms, or army silhouettes are absent.
  • Segment out stable UI when it dominates and the question is the world render; keep a full-frame score too, labeled.
  • If the camera is wrong, pixel scores are diagnostic only. Fix camera intent first, then judge the render.
  • 每次迭代时引用同一配对的前一次和新的差异分数,然后说明变化是趋近目标、偏离目标,还是诊断性噪声。
  • 对于内容缺失类bug,优先使用边缘指标。一张平铺的俯视图可能显示出看似温和的灰度差异,而边缘能量指标能证明树木、道路、城市形态或军队轮廓缺失。
  • 当UI占主导且问题核心是世界渲染时,分割出稳定的UI区域;同时保留带标签的全帧分数。
  • 如果相机角度错误,像素分数仅用于诊断。先修正相机意图,再评判渲染效果。

Tooling

工具

Keep comparison scripts inside the skill or a temporary workspace, not in product code, unless the product genuinely needs screenshot comparison at runtime.
  • scripts/visual-parity-diff.mjs
    is a reusable local helper. Run it with
    REFERENCE_DIR=<png-folder>
    ,
    CANDIDATE_DIR=<png-folder>
    , and optional
    OUT_DIR=<artifact-folder>
    .
    REPORT_ORDER=a,b,c
    pins ordering;
    CROPS_JSON=<file>
    adds labeled crops (keyed by image id, each crop in pixels or
    { "unit": "ratio" }
    normalized bounds).
  • For other tasks, adapt the same artifact set rather than adding one-off scripts to the application. Extend the helper if a needed pair is uncovered.
将对比脚本保存在skill或临时工作区中,而非产品代码中,除非产品确实需要在运行时进行截图对比。
  • scripts/visual-parity-diff.mjs
    是可复用的本地辅助工具。运行时需指定
    REFERENCE_DIR=<png文件夹>
    CANDIDATE_DIR=<png文件夹>
    ,可选指定
    OUT_DIR=<工件文件夹>
    REPORT_ORDER=a,b,c
    可固定排序;
    CROPS_JSON=<文件>
    可添加带标签的裁剪区域(按图片ID索引,每个裁剪区域以像素为单位,或使用
    { "unit": "ratio" }
    归一化边界)。
  • 对于其他任务,调整相同的工件集,而非向应用中添加一次性脚本。如果发现需要新的配对功能,可扩展该辅助工具。

References

参考资料

  • references/subagent-visual-review.md
    : neutral subagent prompt/config for an independent judgment when history could bias you.
  • references/subagent-visual-review.md
    :当历史记录可能影响你的判断时,用于获取独立判断的中立子代理提示/配置。