更多文章可以关注 【 小敏碎讲前端 】
博主最近上班犯困,想找点有趣的东西打发时间,于是乎打开了AI闲聊。
"用CSS能画蒙娜丽莎吗?"
AI信誓旦旦地说:"当然可以!"
作为一个TNT的小小团粉,博主瞬间来了兴趣——既然CSS能画蒙娜丽莎,那画个人应该也不在话下吧?不如让AI试试画我家宋亚轩!
于是,AI展示了一波"神级操作",在博主一次又一次的纠正下,迭代出了4个版本...的宋村村:
编辑
...
等等,这不对吧?我那可盐可甜、帅气迷人的宋芽芽怎么成了这副模样?!
编辑
当然啦,作为团粉肯定要雨露均沾,给博主整笑了,瞬间不困了——
编辑
...
好吧,不管怎样,博主对这个画人物产生了深厚的兴趣,于是就去研究了一下如果用css画人物!
先看看,博主经过研究后画出来的图
编辑
接下来,让博主带你分析一下,这个骚操作到底是怎么实现的。
核心技术:box-shadow
什么是box-shadow?
box-shadow是CSS3中的属性,通常用来给元素添加阴影效果。它的基本语法是:
box-shadow: X偏移 Y偏移 模糊半径 扩展半径 颜色;
像素艺术的魔法
关键技巧在于:当一个元素的width和height都为0时,它的box-shadow会变成独立的像素点!
#art {
width: 0;
height: 0;
box-shadow:
0px 0px 4px 5px #6C6E47,
5px 0px 4px 5px #686B42,
10px 0px 4px 5px #6E7146;
}
看,每一个box-shadow的值就是一个像素点:
- 第一个值:X轴偏移(水平位置)
- 第二个值:Y轴偏移(垂直位置)
4px:模糊半径(让像素边缘柔和)5px:扩展半径(控制像素大小)- 颜色值:像素的颜色
完整示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Mona Lisa - CSS Pixel Art</title>
<style>
body {
background: black;
}
#monalisa {
position: absolute;
top: 30px;
left: 50%;
margin-left: -200px;
width: 0;
height: 0;
box-shadow:
/* 背景暗部 */
0px 0px 4px 5px #6C6E47,
5px 0px 4px 5px #686B42,
/* ... 成千上万行像素数据 ... */
/* 人物面部 */
200px 150px 4px 5px #F5D5B5,
/* ... 更多像素 ... */
/* 背景亮部 */
400px 300px 4px 5px #C7C58D;
}
</style>
</head>
<body>
<div id="monalisa"></div>
</body>
</html>
像素数据是如何生成的?
方法一:使用像素艺术工具手动绘制
原理:用专业的像素绘图软件绘制,然后通过工具或脚本提取颜色数据。
可执行步骤:
Step 1:下载安装工具
- 推荐工具:Aseprite(付费但专业)或 Piskel(免费在线)
- Aseprite官网:aseprite.org/
- Piskel官网:www.piskelapp.com/
Step 2:创建画布
- 新建一个画布,设置尺寸(比如 100x100 像素)
- 缩放画布使每个像素清晰可见
Step 3:绘制图案
- 使用铅笔工具逐像素绘制
- 可以参考蒙娜丽莎的原图,用取色器吸取颜色
Step 4:导出数据
- Aseprite:文件 → 导出 → 选择 CSV 格式
- 或使用脚本导出JSON格式
Step 5:转换为CSS
- 编写脚本解析坐标和颜色,转换为box-shadow格式
Python转换脚本示例:
from PIL import Image
import json
# 打开图片
img = Image.open('mona_lisa.png')
# 逐像素读取
shadows = []
for y in range(img.height):
for x in range(img.width):
r, g, b = img.getpixel((x, y))
if (r, g, b) != (0, 0, 0): # 跳过透明像素
color = f'#{r:02x}{g:02x}{b:02x}'
shadows.append(f'{x * 5}px {y * 5}px 4px 5px {color}')
# 输出
print('box-shadow:')
print(',\n'.join(shadows) + ';')
注意事项:
- 像素越大,生成的数据越少,但精度越低
- 建议像素尺寸设为5x5或10x10平衡效果和代码量
方法二:图像转换工具自动生成
原理:使用现成的转换工具,将任意图片一键转换为box-shadow代码。
可执行步骤:
Step 1:访问在线转换工具
- Pixelator(强烈推荐):elrumordelaluz.github.io/Pixelator/
- MiniShadowArt(亲测有效,快速转换) :xem.github.io/miniShadowA…
- Pixel Art Canvas:iotools.cloud/tool/pixel-…
Step 2:上传图片
- 支持 JPG、PNG 格式
- 建议使用对比度高的图片效果更好
Step 3:调整参数
- Pixel Size:每个像素的大小(推荐5-10)
- Canvas Size:输出画布尺寸
- Background Color:背景色
Step 4:预览并调整
- 实时预览效果
- 可以局部调整颜色或重新采样
Step 5:复制代码
- 点击"Export"或"Copy CSS"
- 粘贴到你的HTML文件中
推荐工具列表:
| 工具名称 | 网址 | 特点 |
|---|---|---|
| Pixelator | elrumordelaluz.github.io/Pixelator | 实时预览,支持调色板,最推荐 |
| MiniShadowArt | xem.github.io/miniShadowArt | 可直接拖拽图片转换,轻量级 |
| Pixel Art Canvas | iotools.cloud/tool/pixel-art-canvas | 可自己画也支持图片转换,多种调色板 |
| CSS Pixel Art Generator | dev.to/smpnjn/css-pixel-art-generator | 40x40网格,支持上传图片 |
高级技巧:
- 先用PS或Figma将图片处理成灰度或简化配色
- 再用转换工具生成代码,效果更接近原图
方法三:代码脚本批量处理
原理:自己编写脚本,精确控制转换过程,适合需要批量处理或自定义格式的场景。
可执行步骤:
Step 1:准备环境
- Python 3.x:官网 python.org
- Node.js(可选):官网 nodejs.org
- 浏览器控制台(最简单):直接用浏览器
Python方案:
#!/usr/bin/env python3
"""
图片转CSS box-shadow像素艺术
用法: python image_to_css.py 输入图片.png 输出.html
"""
from PIL import Image
import sys
def image_to_css(input_path, output_path, pixel_size=5, bg_color='#000000'):
"""转换图片为CSS代码"""
img = Image.open(input_path)
img = img.convert('RGB') # 确保是RGB模式
width, height = img.size
shadows = []
for y in range(height):
for x in range(width):
r, g, b = img.getpixel((x, y))
color = f'#{r:02x}{g:02x}{b:02x}'
pos_x = x * pixel_size
pos_y = y * pixel_size
shadows.append(f'{pos_x}px {pos_y}px 4px 5px {color}')
html_template = f'''<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CSS Pixel Art</title>
<style>
body {{
background: {bg_color};
}}
.pixel-art {{
position: absolute;
width: 0;
height: 0;
box-shadow: {','.join(shadows)};
}}
</style>
</head>
<body>
<div class="pixel-art"></div>
</body>
</html>'''
with open(output_path, 'w', encoding='utf-8') as f:
f.write(html_template)
print(f'Done! Generated {len(shadows)} pixels')
if __name__ == '__main__':
image_to_css('input.png', 'output.html')
Node.js方案(无需安装依赖):
// 使用 jimp 库
const Jimp = require('jimp');
async function imageToCss(inputPath, outputPath) {
const image = await Jimp.read(inputPath);
const shadows = [];
image.scan(0, 0, image.bitmap.width, image.bitmap.height, function(x, y, idx) {
const r = this.bitmap.data[idx + 0];
const g = this.bitmap.data[idx + 1];
const b = this.bitmap.data[idx + 2];
const color = `#${r.toString(16).padStart(2,'0')}${g.toString(16).padStart(2,'0')}${b.toString(16).padStart(2,'0')}`;
shadows.push(`${x * 5}px ${y * 5}px 4px 5px ${color}`);
});
console.log('box-shadow:');
console.log(shadows.join(',\n') + ';');
}
imageToCss('mona_lisa.jpg', 'output.css');
浏览器控制台方案(最简单,无需安装任何东西):
// 在浏览器控制台运行
// 先用 canvas 加载图片
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = () => {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
const shadows = [];
for (let y = 0; y < img.height; y++) {
for (let x = 0; x < img.width; x++) {
const pixel = ctx.getImageData(x, y, 1, 1).data;
const color = `#${pixel[0].toString(16).padStart(2,'0')}${pixel[1].toString(16).padStart(2,'0')}${pixel[2].toString(16).padStart(2,'0')}`;
shadows.push(`${x * 5}px ${y * 5}px 4px 5px ${color}`);
}
}
console.log('box-shadow:\n' + shadows.join(',\n') + ';');
};
img.src = 'mona_lisa.jpg'; // 改成你的图片路径
运行命令:
# Python
pip install pillow
python image_to_css.py mona_lisa.jpg mona_lisa.html
# Node.js
npm install jimp
node image_to_css.js
为什么这个方法有效?
- 零尺寸元素:一个
width: 0; height: 0的元素本身不可见 - 阴影独立:每个box-shadow都是独立渲染的
- 性能优化:现代浏览器对box-shadow的渲染做了大量优化
- 可维护性:虽然代码看起来很长,但逻辑其实很简单
优势与局限
优势
- 纯CSS实现,无需JavaScript
- 文件体积小(比PNG图片小很多)
- 完全可缩放
- 可以用CSS动画
局限
- 代码量大(蒙娜丽莎这幅画用了7000多行)
- 修改困难(要改一根头发丝都得找半天)
- 不适合复杂图像
扩展应用
除了静态图像,这个技术还可以用来:
- 加载动画:小像素点的动态组合
- 游戏角色:复古风格的游戏
- 数据可视化:用像素表示数据分布
- Logo和图标:小型简约图案
结语
用CSS的box-shadow来画像素艺术,是一个非常巧妙的技术。它展示了CSS的灵活性——这个属性原本只是用来添加阴影的,但通过巧妙的设置,它能变成一个强大的像素绘图工具。
如果你也想尝试,可以从简单的图案开始,比如画一个小方块、一颗爱心