我用 CSS 画了个蒙娜丽莎!超详细步骤

0 阅读7分钟

更多文章可以关注 【 小敏碎讲前端 】

博主最近上班犯困,想找点有趣的东西打发时间,于是乎打开了AI闲聊。

"用CSS能画蒙娜丽莎吗?"

AI信誓旦旦地说:"当然可以!"

作为一个TNT的小小团粉,博主瞬间来了兴趣——既然CSS能画蒙娜丽莎,那画个人应该也不在话下吧?不如让AI试试画我家宋亚轩!

于是,AI展示了一波"神级操作",在博主一次又一次的纠正下,迭代出了4个版本...的宋村村:

​编辑

...

等等,这不对吧?我那可盐可甜、帅气迷人的宋芽芽怎么成了这副模样?!

​编辑

当然啦,作为团粉肯定要雨露均沾,给博主整笑了,瞬间不困了——

​编辑

...

好吧,不管怎样,博主对这个画人物产生了深厚的兴趣,于是就去研究了一下如果用css画人物!

先看看,博主经过研究后画出来的图
​编辑

接下来,让博主带你分析一下,这个骚操作到底是怎么实现的。

核心技术:box-shadow

什么是box-shadow?

box-shadow是CSS3中的属性,通常用来给元素添加阴影效果。它的基本语法是:

box-shadow: X偏移 Y偏移 模糊半径 扩展半径 颜色;

像素艺术的魔法

关键技巧在于:当一个元素的widthheight都为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:下载安装工具

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:访问在线转换工具

Step 2:上传图片

  • 支持 JPG、PNG 格式
  • 建议使用对比度高的图片效果更好

Step 3:调整参数

  • Pixel Size:每个像素的大小(推荐5-10)
  • Canvas Size:输出画布尺寸
  • Background Color:背景色

Step 4:预览并调整

  • 实时预览效果
  • 可以局部调整颜色或重新采样

Step 5:复制代码

  • 点击"Export"或"Copy CSS"
  • 粘贴到你的HTML文件中

推荐工具列表

工具名称网址特点
Pixelatorelrumordelaluz.github.io/Pixelator实时预览,支持调色板,最推荐
MiniShadowArtxem.github.io/miniShadowArt可直接拖拽图片转换,轻量级
Pixel Art Canvasiotools.cloud/tool/pixel-art-canvas可自己画也支持图片转换,多种调色板
CSS Pixel Art Generatordev.to/smpnjn/css-pixel-art-generator40x40网格,支持上传图片

高级技巧

  • 先用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


为什么这个方法有效?

  1. 零尺寸元素:一个width: 0; height: 0的元素本身不可见
  2. 阴影独立:每个box-shadow都是独立渲染的
  3. 性能优化:现代浏览器对box-shadow的渲染做了大量优化
  4. 可维护性:虽然代码看起来很长,但逻辑其实很简单

优势与局限

优势

  • 纯CSS实现,无需JavaScript
  • 文件体积小(比PNG图片小很多)
  • 完全可缩放
  • 可以用CSS动画

局限

  • 代码量大(蒙娜丽莎这幅画用了7000多行)
  • 修改困难(要改一根头发丝都得找半天)
  • 不适合复杂图像

扩展应用

除了静态图像,这个技术还可以用来:

  1. 加载动画:小像素点的动态组合
  2. 游戏角色:复古风格的游戏
  3. 数据可视化:用像素表示数据分布
  4. Logo和图标:小型简约图案

结语

用CSS的box-shadow来画像素艺术,是一个非常巧妙的技术。它展示了CSS的灵活性——这个属性原本只是用来添加阴影的,但通过巧妙的设置,它能变成一个强大的像素绘图工具。

如果你也想尝试,可以从简单的图案开始,比如画一个小方块、一颗爱心