不会photoshop? 也能用canvas把头像设计成彩虹色🌈

简介: 不会photoshop? 也能用canvas把头像设计成彩虹色🌈

编码🌈


颜色提取✨

首先给大家看一下我的原始头像吧:


网络异常,图片无法展示
|


首先我要把绿色的部分提取出来,并把灰色的圆形背景去掉


let myCanvas = document.getElementById("my-canvas");
let cxt = myCanvas.getContext("2d");
const hancaoImage = new Image();
hancaoImage.src = "hancao.jpeg";
// 我原本头像的大小
hancaoImage.width = 212;
hancaoImage.height = 199;
hancaoImage.onload = function () {
  myCanvas.width = hancaoImage.width;
  myCanvas.height = hancaoImage.height;
  cxt.drawImage(hancaoImage, 0, 0);
  let imageData = cxt.getImageData(0, 0, hancaoImage.width, hancaoImage.height).data;
  // 白色填充
  cxt.fillStyle = "#ffffff";
  cxt.fillRect(0, 0, 212, 199);
  let list = [];
  for (let h = 0; h < hancaoImage.height; h += 1) {
    for (let w = 0; w < hancaoImage.width; w += 1) {
      let position = (hancaoImage.width * h + w) * 4;
      let r = imageData[position], g = imageData[position + 1], b = imageData[position + 2], a = imageData[position + 3];
      // 给定颜色范围,把符合范围的点的放入list数组以便进行后续处理
      if (((r + g + b) < 665) && (r + g + b) > 410) {
        cxt.fillStyle = `rgba(166, 166, 255, 1)`;
        cxt.fillRect(w, h, 1, 1);
        list.push({
          h,
          w
        })
      } else if((r + g + b) < 410){
        cxt.fillStyle = `rgb(0,0,0)`;
        cxt.fillRect(w, h, 1, 1);
      }
    }
  }


效果就先变成了这样,我这时候已经把紫色的部分的点存在了数组里。


网络异常,图片无法展示
|


绘制多种颜色✨


下面我需要绘制多种颜色,像彩虹一样🌈


const colorList = [
    '252,240,91',
    '119,246,220',
    '92,219,138',
    '241,160,149',
    '252,240,91',
    '92,219,138',
    '119,246,220',
  ];
  const colorLength = colorList.length;
  const step = Math.floor(list.length / colorLength);
  for(let index = 0; index < list.length; index++) {
    const colorIndex = Math.floor(index/step);
    let color = colorList[colorIndex] || colorList[colorLength - 1];
    cxt.fillStyle = `rgb(${color})`;
    cxt.fillRect(list[index].w, list[index].h, 1, 1);
  }
}


效果就变成了这样:


网络异常,图片无法展示
|

好丑啊~


颜色渐变✨


我陷入了僵局,十分的痛苦,我精心设计的头像不好看,岂不是白瞎了我写的代

码。。。


之后我受到了高人点拨:


网络异常,图片无法展示
|


对!加渐变!


const colorLength = colorList.length;
const step = Math.floor(list.length / colorLength);
for(let index = 0; index < list.length; index++) {
    const colorIndex = Math.floor(index/step);
    let color = colorList[colorIndex] || colorList[colorLength - 1];
    if(colorIndex < colorLength - 1){
      const percent = (index%step) / step;
      const colorFront = colorList[colorIndex].split(',');
      const colorBehind = colorList[colorIndex + 1].split(',');
      const rx = Number(colorBehind[0]) - Number(colorFront[0]);
      const gx = Number(colorBehind[1]) - Number(colorFront[1]);
      const bx = Number(colorBehind[2]) - Number(colorFront[2]);
      color = `${Number(colorFront[0])+Math.floor(rx * percent)},${Number(colorFront[1])+Math.floor(gx * percent)},${Number(colorFront[2])+Math.floor(bx * percent)}`;
    }
    cxt.fillStyle = `rgb(${color})`;
    cxt.fillRect(list[index].w, list[index].h, 1, 1);
}


我就是在颜色数组做差,逐渐趋近,思路很简单~

之后效果就变成了这样子:


网络异常,图片无法展示
|

好看点了,但是总感觉有一点廉价~


磨砂感✨


廉价就加入磨砂,加入颗粒感!请叫我大聪明~


color = color.split(',').map(item => {
  const flag = Math.random() > 0.5;
  const random = Math.floor( 15 * Math.random());
  if(flag){
    return Number(item) - random;
  }
  return Number(item) + random;
}).join(',');


其实就是对当前点的颜色做一点随机的加减


网络异常,图片无法展示
|


诶呀,感觉饱满起来了~

效果达成✨

当然别走开,后面还有精心调制的颜色,以及彩蛋~


完整代码✨


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>寒草头像</title>
  <style>
    #my-canvas {
      position: absolute;
      left: 30vw;
      top: 20vh;
    }
  </style>
</head>
<body>
  <canvas id="my-canvas"></canvas>
  <script>
    let myCanvas = document.getElementById("my-canvas");
    let cxt = myCanvas.getContext("2d");
    const hancaoImage = new Image();
    hancaoImage.src = "hancao.jpeg";
    hancaoImage.width = 212;
    hancaoImage.height = 199;
    hancaoImage.onload = function () {
      myCanvas.width = hancaoImage.width;
      myCanvas.height = hancaoImage.height;
      cxt.drawImage(hancaoImage, 0, 0);
      let imageData = cxt.getImageData(0, 0, hancaoImage.width, hancaoImage.height).data;
      cxt.fillStyle = "#ffffff";
      cxt.fillRect(0, 0, 212, 199);
      let list = [];
      for (let h = 0; h < hancaoImage.height; h += 1) {
        for (let w = 0; w < hancaoImage.width; w += 1) {
          let position = (hancaoImage.width * h + w) * 4;
          let r = imageData[position], g = imageData[position + 1], b = imageData[position + 2], a = imageData[position + 3];
          if (((r + g + b) < 665) && (r + g + b) > 410) {
            cxt.fillStyle = `rgba(166, 166, 255, 1)`;
            cxt.fillRect(w, h, 1, 1);
            list.push({
              h,
              w
            })
          } else if((r + g + b) < 410){
            cxt.fillStyle = `rgb(0,0,0)`;
            cxt.fillRect(w, h, 1, 1);
          }
        }
      }
      const colorList = [
        '79,181,118',
        '68,196,137',
        '40,169,174',
        '40,162,183',
        '76,119,136',
        '108,79,99',
        '67,44,57',
      ]
      const colorLength = colorList.length;
      const step = Math.floor(list.length / colorLength);
      for(let index = 0; index < list.length; index++) {
        const colorIndex = Math.floor(index/step);
        let color = colorList[colorIndex] || colorList[colorLength - 1];
        if(colorIndex < colorLength - 1){
          const percent = (index%step) / step;
          const colorFront = colorList[colorIndex].split(',');
          const colorBehind = colorList[colorIndex + 1].split(',');
          const rx = Number(colorBehind[0]) - Number(colorFront[0]);
          const gx = Number(colorBehind[1]) - Number(colorFront[1]);
          const bx = Number(colorBehind[2]) - Number(colorFront[2]);
          color = `${Number(colorFront[0])+Math.floor(rx * percent)},${Number(colorFront[1])+Math.floor(gx * percent)},${Number(colorFront[2])+Math.floor(bx * percent)}`;
        }
        color = color.split(',').map(item => {
          const flag = Math.random() > 0.5;
          const random = Math.floor( 15 * Math.random());
          if(flag){
            return Number(item) - random;
          }
          return Number(item) + random;
        }).join(',');
        cxt.fillStyle = `rgb(${color})`;
        cxt.fillRect(list[index].w, list[index].h, 1, 1);
      }
    }
  </script>
</body>
</html>


最终效果✨

网络异常,图片无法展示
|


富有层次,而且还有比较高级的颗粒感,真的很漂亮~


感谢大鹅🦢给我挑颜色~


于是我想感激大鹅,无以为报,只有以身。。。体力行的作品作为回报了:


网络异常,图片无法展示
|


我不会被骂吧。。。


结束语🌈


网络异常,图片无法展示
|


找寻学习前端最初始的快乐与成就感,尽在草系前端的前端冰可乐


写在最后


如果彩虹有第八种颜色

那就是你

祝大家拥有五彩斑斓的生活

伙伴们,如果喜欢我的文章,可以点赞 👍  关注➕ ,这是对我最大的支持。


相关文章
|
Web App开发 安全
navigator.mediaDevices是undefined怎么办
navigator.mediaDevices是undefined怎么办
2910 1
|
移动开发 前端开发 API
HTML5 Canvas 实现简易 绘制音乐环形频谱图
参考资料:1.Web 技术研究所2.Web_Audio_API 0.启发 在B站我们有很多的小伙伴们应该都看到过用AE做的可视化音乐播放器播放音乐的视频,看着特别酷炫带感有木有。
3905 0
|
4月前
|
人工智能 资源调度 安全
意图共鸣科技发布《认知智能白皮书》:AI认知架构(CA)与认知操作系统(COS)——如何解决大模型“能做事但不懂事”的结构性缺陷
《认知智能白皮书》由东莞市意图共鸣科技有限公司创始人陈金桥于2026年5月发布。直指大模型“能力强但无分寸”的结构性缺失,首创“认知架构(CA)+认知操作系统(COS)”双层框架,为AI构建类神经系统的感知、判断与调度能力,推动从“裸算力”迈向可信赖的认知智能。
407 5
|
存储 机器学习/深度学习 人工智能
|
存储 安全 Java
Java 集合面试题从数据结构到 HashMap 源码剖析详解及长尾考点梳理
本文深入解析Java集合框架,涵盖基础概念、常见集合类型及HashMap的底层数据结构与源码实现。从Collection、Map到Iterator接口,逐一剖析其特性与应用场景。重点解读HashMap在JDK1.7与1.8中的数据结构演变,包括数组+链表+红黑树优化,以及put方法和扩容机制的实现细节。结合订单管理与用户权限管理等实际案例,展示集合框架的应用价值,助你全面掌握相关知识,轻松应对面试与开发需求。
709 3
|
人工智能 安全 网络安全
借助 SentinelOne 全新的风险保障计划变革网络安全保险市场
2025年信息技术系统故障凸显技术风险即商业风险。SentinelOne与多家顶尖保险公司合作推出“风险保障计划”,通过Singularity™平台结合AI技术,助力企业提前阻止攻击、减少财务损失。该计划提供高达100万美元的数据泄露响应保障,并支持安全数据共享以优化保单激励。SentinelOne连续三年获评Gartner领导者,其解决方案为中小企业和中型市场企业提供全面网络安全防护,确保业务安心无忧。
442 1
|
数据采集 物联网 API
理解异步编程:从日常场景到代码逻辑
异步编程是现代高并发应用开发的核心技术之一。通过Python的asyncio库,利用事件循环机制与协程,可高效处理I/O密集型任务。相比同步模式,异步能显著减少资源闲置,如在Web请求、文件读写时“变废为宝”。文章从同步与异步对比、协程原理、事件循环机制,到实战案例(爬虫性能测试)及常见误区解决,全面解析异步编程。其适用于高并发I/O场景,但不推荐用于CPU密集型任务。掌握异步编程,如同拥有精巧工具,在合适场景下大幅提升系统性能。
876 0
|
编解码 虚拟化 Windows
通过Hyper分辨率适配技术,可以解决虚拟机显示器上的分辨率适配难题
Hyper-V的增强会话模式通过RDP协议实现虚拟机与物理显示器的高质量连接,支持更高分辨率、优化图形性能,并提供共享剪贴板、拖放文件等增强功能。启用此模式可解决虚拟机分辨率适配难题,提升显示效果和交互性。需确保操作系统支持RDP,网络稳定,且注意对主机性能的影响。
|
机器学习/深度学习 人工智能 算法
《C++与 BLAS、LAPACK:加速人工智能算法的线性代数秘籍》
本文探讨了线性代数在人工智能中的核心地位及其对算法性能的影响,重点介绍了 C++ 中的 BLAS 和 LAPACK 库。这些库通过高效的基础线性代数运算和高级矩阵操作,显著提升了神经网络、数据降维和推荐系统等算法的计算效率。文章还详细讲解了如何在 C++ 项目中集成和优化这些库,以实现更好的性能。
746 19
|
机器学习/深度学习 人工智能 运维
智能运维:AI驱动的IT运维革命###
【10月更文挑战第21天】 随着数字化转型的深入,智能运维(AIOps)正逐步成为企业IT管理的核心。本文将探讨AI技术如何赋能运维领域,通过自动化、智能化手段提升系统稳定性和效率,降低运营成本,并分享实施智能运维的最佳实践与挑战应对策略。 ###
1559 1

热门文章

最新文章