关于 image-treatment
image-treatment 是用于网页界面图像设计的技能,介绍 CSS 滤镜、混合模式、遮罩、叠加层、SVG 滤镜、自适应图像处理和视觉检查。
主要功能
- 01CSS 滤镜与混合模式
- 02双色调效果与图像遮罩
- 03分层背景和叠加层
- 04自适应图像变体
- 05SVG 滤镜与视觉效果
- 06无障碍与截图检查
适用场景
- 01为照片应用双色调效果
- 02在主视觉图上添加清晰可读的文字
- 03创建自适应图像网格和裁切
- 04检查不同视口下的图像效果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ arnavpuri/ designskills --skill image-treatment安装后在 Claude Code 中输入/image-treatment确认已加载。
详细介绍
图像处理
使用 CSS 滤镜、混合模式、遮罩和 SVG 滤镜,为图像应用惊艳的视觉效果。
前置条件
- 阅读
.agents/design-context.md(参见design-context),了解品牌颜色(双色调和叠加颜色应来自 Color System)、风格原型和图像方向。以下颜色使用共享的--brand-*/--gray-*色阶。 - 确定图像的情绪和用途:编辑、产品、营销或艺术。
- 如果源图像尚不存在,请使用
image-generation技能(python <image-generation>/scripts/gemini-generate.py)创建,然后在此处进行处理。对于必须烘焙到文件中的处理(社交媒体图片、电子邮件、OG 图片),请使用 Pillow,而不是 CSS。
步骤 1:CSS 滤镜组合
单项滤镜
| 滤镜 | 范围 | 效果 |
|---|---|---|
| brightness() | 0-2+ | 调暗(< 1)或调亮(> 1) |
| contrast() | 0-2+ | 降低(< 1)或增强(> 1)对比度 |
| saturate() | 0-3+ | 降低饱和度(0)或增强鲜艳度(> 1) |
| grayscale() | 0-1 | 去除颜色 |
| sepia() | 0-1 | 暖色复古色调 |
| hue-rotate() | 0-360deg | 偏移所有色相 |
| blur() | 0-20px+ | 高斯模糊 |
预设滤镜配方
.filter-vintage { filter: sepia(0.3) contrast(1.1) brightness(1.05) saturate(0.9); }
.filter-cool { filter: saturate(0.85) contrast(1.1) brightness(1.02) hue-rotate(-10deg); }
.filter-bw { filter: grayscale(1) contrast(1.4) brightness(1.05); }
.filter-dreamy { filter: brightness(1.1) contrast(0.9) saturate(1.2) blur(0.5px); }
.filter-faded { filter: contrast(0.85) brightness(1.1) saturate(0.7); }
.filter-moody { filter: brightness(0.85) contrast(1.2) saturate(0.8); }
.filter-vivid { filter: contrast(1.15) saturate(1.4) brightness(1.02); }
使用滤镜实现悬停效果
.image-card img { filter: grayscale(0.8) brightness(0.9); transition: filter 0.4s ease; }
.image-card:hover img { filter: grayscale(0) brightness(1); }
步骤 2:混合模式技巧
常见混合模式
| 模式 | 效果 | 用途 |
|---|---|---|
| multiply | 使颜色变暗(白色消失) | 颜色着色、去除白色背景 |
| screen | 使颜色变亮(黑色消失) | 发光效果 |
| overlay | 增强对比度 | 颜色叠加 |
| soft-light | 柔和叠加 | 轻柔着色 |
| color | 应用色相和饱和度,同时保留亮度 | 为照片着色 |
| luminosity | 从图层获取亮度,从下方内容获取色相和饱和度 | 重新着色纹理 |
为图像添加颜色叠加
.image-container { position: relative; }
.image-container::after {
content: ''; position: absolute; inset: 0;
background: var(--brand-500); mix-blend-mode: multiply; opacity: 0.6;
}
步骤 3:图像双色调效果
将图像的亮部映射为一种颜色,将暗部映射为另一种颜色。
纯 CSS 双色调
灰度图像与高光颜色正片叠底(白色 → 高光色,黑色 → 黑色),然后由阴影颜色提亮暗部(黑色 → 阴影色)。高光色在每个 RGB 通道中都必须比阴影色更亮。
.duotone { position: relative; isolation: isolate; background: #e2b94c; /* highlight */ }
.duotone img { display: block; width: 100%; filter: grayscale(1) contrast(1.2); mix-blend-mode: multiply; }
.duotone::after {
content: ''; position: absolute; inset: 0; pointer-events: none;
background: #1a1a2e; /* shadow */ mix-blend-mode: lighten;
}
SVG 滤镜双色调(精确映射,适用于任何元素)
tableValues 分别是阴影色 → 高光色各通道在 0-1 范围内的值(十六进制值 ÷ 255):#1a1a2e → #e2b94c。
<svg width="0" height="0" aria-hidden="true" style="position:absolute">
<filter id="duotone-gold" color-interpolation-filters="sRGB">
<feColorMatrix type="matrix" values="0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0"/>
<feComponentTransfer>
<feFuncR type="table" tableValues="0.102 0.886"/>
<feFuncG type="table" tableValues="0.102 0.725"/>
<feFuncB type="table" tableValues="0.180 0.298"/>
</feComponentTransfer>
</filter>
</svg>
<img src="photo.jpg" alt="…" style="filter: url(#duotone-gold)">
常见双色调搭配
| 阴影色 | 高光色 | 风格 |
|---|---|---|
| #1a1a2e | #e2b94c | 奢华、金色+海军蓝 |
| #0d1b2a | #3498db | 科技、冷蓝色 |
| #2d1b4e | #ff6b6b | 创意、大胆 |
| #1b3a2a | #a7f3d0 | 自然、绿色 |
步骤 4:图像遮罩
clip-path 形状
.clip-circle { clip-path: circle(50%); }
.clip-rounded { clip-path: inset(0 round 1rem); }
.clip-diagonal { clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%); }
.clip-hexagon { clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%); }
使用 mask-image 实现渐变淡出
.image-fade-bottom {
mask-image: linear-gradient(to bottom, black 60%, transparent 100%);
-webkit-mask-image: linear-gradient(to bottom, black 60%, transparent 100%);
}
.image-vignette {
mask-image: radial-gradient(ellipse 70% 70% at center, black 50%, transparent 100%);
-webkit-mask-image: radial-gradient(ellipse 70% 70% at center, black 50%, transparent 100%);
}
文字形状遮罩
.image-text-mask {
background-image: url('photo.jpg'); background-size: cover;
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
background-clip: text; font-size: 8rem; font-weight: 900;
color: transparent; /* fallback if background-clip: text is unsupported */
}
仅用于展示尺寸的装饰性文字;字母下方的照片仍必须与页面背景保持 3:1 的对比度,并且元素应保留供屏幕阅读器读取的真实文本。
步骤 5:背景图像技巧
完全覆盖背景
.hero-bg {
background: url('hero.jpg') center/cover no-repeat;
min-height: 80vh;
}
固定 / 视差背景
.parallax-section {
background: url('bg.jpg') center/cover no-repeat;
background-attachment: fixed;
min-height: 60vh;
}
@media (hover: none), (prefers-reduced-motion: reduce) {
.parallax-section { background-attachment: scroll; } /* iOS ignores fixed; parallax can trigger vestibular issues */
}
多层背景
.layered-bg {
background:
linear-gradient(to bottom, rgba(0,0,0,0.4), rgba(0,0,0,0.7)),
url('pattern.svg') repeat center / 64px 64px,
url('photo.jpg') no-repeat center / cover;
}
步骤 6:图像叠加模式
渐变叠加(提升文本可读性)
.image-overlay-gradient { position: relative; }
.image-overlay-gradient::after {
content: ''; position: absolute; inset: 0;
background: linear-gradient(to top, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0.3) 40%, transparent 100%);
}
.image-overlay-gradient .content { position: relative; z-index: 1; color: white; }
图片上的文本仍须符合 WCAG 对比度要求:相对于其背后最亮的像素,对比度需达到 4.5:1(若字号 ≥24px 或粗体字号 ≥18.66px,则需达到 3:1)。检查渲染截图中文本下方的区域,而非图片的平均值;逐步增强叠加效果,直至达标。
悬停显示叠加层
.card-image { position: relative; overflow: hidden; }
.card-image .overlay {
position: absolute; inset: 0;
background: oklch(from var(--brand-500) l c h / 0.85);
display: grid; place-items: center; opacity: 0; transition: opacity 0.3s ease;
}
.card-image:hover .overlay { opacity: 1; }
第 7 步:图像网格与拼贴布局
瀑布流样式网格
.image-grid-masonry { columns: 3; column-gap: 1rem; }
.image-grid-masonry img { display: block; width: 100%; margin-bottom: 1rem; border-radius: 0.5rem; break-inside: avoid; }
/* Note: columns flow top-to-bottom, so DOM/reading order runs down each column, not across rows */
@media (max-width: 768px) { .image-grid-masonry { columns: 2; } }
@media (max-width: 480px) { .image-grid-masonry { columns: 1; } }
CSS 网格拼贴
.image-collage {
display: grid; grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 200px); gap: 0.5rem;
}
.image-collage img:nth-child(1) { grid-column: 1 / 3; grid-row: 1 / 3; }
.image-collage img { width: 100%; height: 100%; object-fit: cover; border-radius: 0.5rem; }
第 8 步:响应式图像艺术指导
分辨率切换(相同裁剪,多种尺寸)
w 描述符列出每个文件的实际像素宽度;sizes 告诉浏览器图像显示时的宽度,以便浏览器在布局前选择图像。如果不设置 sizes,浏览器会假定图像宽度为 100vw。
<img src="card-800.jpg"
srcset="card-400.jpg 400w, card-800.jpg 800w, card-1200.jpg 1200w, card-1600.jpg 1600w"
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 400px"
alt="Team reviewing designs at a whiteboard" width="800" height="600"
loading="lazy" decoding="async">
艺术指导 + 现代格式(<picture>)
浏览器会采用第一个匹配的 <source>,因此要先按媒体查询排序,再按格式排序(AVIF 排在 WebP 前)。每个 source 都有自己的 srcset/sizes;<source> 上的 width/height 可为不同断点设置不同的宽高比。
<picture>
<source media="(max-width: 640px)" type="image/avif"
srcset="hero-mobile-640.avif 640w, hero-mobile-1280.avif 1280w" sizes="100vw" width="1280" height="1600">
<source media="(max-width: 640px)" type="image/webp"
srcset="hero-mobile-640.webp 640w, hero-mobile-1280.webp 1280w" sizes="100vw" width="1280" height="1600">
<source type="image/avif" srcset="hero-1600.avif 1600w, hero-2400.avif 2400w" sizes="100vw">
<source type="image/webp" srcset="hero-1600.webp 1600w, hero-2400.webp 2400w" sizes="100vw">
<img src="hero-1600.jpg" alt="Describe what the hero shows" width="1600" height="900"
fetchpriority="high" decoding="async">
</picture>
关键规则
- 始终包含
width和height属性(即固有宽高比),以防止布局偏移;CSS 仍可通过width: 100%; height: auto让图像自适应。 - 对首屏以下的图像使用
loading="lazy"。切勿延迟加载 LCP/主视觉图像——让它保持急切加载(默认行为),并添加fetchpriority="high"。 - 使用
decoding="async",避免解码阻塞渲染。 - 格式:AVIF(体积最小,当前所有主流浏览器均支持)→ WebP →
<img src>中的 JPEG 后备格式。仅在图形需要透明度或锐利边缘时使用 PNG/SVG;AVIF 质量设为约 50-65、WebP 质量设为约 75-80,是不错的起点。 alt用于描述图像的用途;装饰性图像使用alt=""。
生成变体
from PIL import Image # pip install Pillow (AVIF built in since Pillow 11.2; check features.check("avif"))
src = Image.open("hero.png").convert("RGB")
for w in (640, 1280, 1600, 2400):
im = src.resize((w, round(src.height * w / src.width)), Image.LANCZOS)
im.save(f"hero-{w}.webp", quality=78)
im.save(f"hero-{w}.avif", quality=55)
im.save(f"hero-{w}.jpg", quality=82, optimize=True, progressive=True)
第 9 步:用于高级效果的 SVG 滤镜
磨砂玻璃
.frosted-glass { backdrop-filter: blur(12px) saturate(180%); background: rgba(255,255,255,0.7); }
@supports not (backdrop-filter: blur(1px)) { .frosted-glass { background: rgba(255,255,255,0.92); } } /* keep text readable */
噪点/颗粒纹理
<svg width="0" height="0" aria-hidden="true" style="position:absolute">
<filter id="noise">
<feTurbulence type="fractalNoise" baseFrequency="0.65" numOctaves="3" stitchTiles="stitch"/>
<feColorMatrix type="saturate" values="0"/>
<feBlend in="SourceGraphic" mode="multiply"/>
</filter>
</svg>
投影(沿形状边缘)
.shaped-shadow { filter: drop-shadow(0 4px 8px rgba(0,0,0,0.2)); }
第 10 步:Object-Fit 与 Object-Position
| 值 | 行为 |
|---|---|
| cover | 填满容器,裁掉多余部分(最常用) |
| contain | 完整显示,可能留有空白 |
| fill | 拉伸以填满容器(会变形) |
| scale-down | 类似 contain,但不会放大 |
.card-image { width: 100%; height: 200px; object-fit: cover; object-position: center; }
.portrait { object-fit: cover; object-position: center top; }
.thumbnail { aspect-ratio: 1; object-fit: cover; border-radius: 0.75rem; }
快速参考
- 使用 CSS
filter快速处理照片效果(组合使用亮度、对比度和饱和度)。 - 使用
mix-blend-mode: multiply在图像上叠加颜色。 - 双调 = 灰度图像 + 双色混合图层。
- 使用
clip-path创建几何蒙版;使用mask-image创建渐变淡出效果。 - 在移动设备上始终禁用
background-attachment: fixed(@media (hover: none))。 - 叠加图层:在图像上使用由下至上的渐变,以提升文本可读性。
- 使用
<picture>实现艺术指导(在不同断点采用不同裁剪)。 - 内容图像始终包含
width、height、alt,以及srcset+sizes;仅对首屏以下的图像进行延迟加载。 - 使用
object-fit: cover+aspect-ratio,确保图像容器一致。 - 使用 SVG 滤镜(噪点、黏合、位移)实现 CSS 无法达到的效果。
验证处理效果
渲染页面并截图(npx playwright screenshot --full-page "file://$PWD/index.html" out.png,移动端另加 --viewport-size=375,800,并添加 --color-scheme=dark),然后使用 Read 查看图像。检查:在任何宽度下,人脸和产品都没有被 object-fit/clip-path 裁掉;图像上的文本在对比度最差的位置仍能达标;双调/滤镜仍符合品牌风格(没有显得浑浊);不支持混合模式或滤镜时,页面也不会出现异常。在浏览器中确认加载了正确的 srcset 候选图像(img.currentSrc),且主视觉图像未启用延迟加载。