一起网易云 ????

网易云音乐想必是大家很熟悉的一款 app 了,毕竟大家在深夜都会网抑云开玩笑了,最近在网易云听歌时,发现了一个很有意思的特效:

就是切换歌曲时,会根据当前封面替换背景色。作为资深切图仔,我那该死的好奇心兜不住了,不行,我要去一探究竟。首先我构思了很多它可能的实现方式:

  • 机器学习对图片进行色彩分析

  • 前端提取图片主色调,做渐变处理

  • 封面背景图做高斯模糊

对于第一种,他不在我的知识范围内,这里就不展开说明了 ????。

第二种的话,一般都是利用canvas来实现。

第三种相对来说,从技术层面来看,实现上是最为简单的。

做了猜测分析后,我默默打开了熟悉的 Chrome 控制台,打开了网易云音乐的源代码:

好家伙,果然是第三种实现方式。????

本来到这里,本文就该结束了。但之前也有朋友问过我如何对前端图片主题色进行提取的问题,正好之前也做过类似的需求,这里就展开做个说明吧。

我们这里以一个图片网站为例,来展示实际业务中应用较广的场景:在弱网下,图片加载速度较慢,此时在图片完全加载之前,提取图片的主色调,然后填充为背景色。这样用户体验能有较大的提升。

那具体是怎么实现的呢?????

我们这里采用canvas来实现,具体分为三步:

  • 获取图片数据

  • 对图片数据进行处理

  • 对颜色列表排序

这里我们使用的测试图片为:

相对来说,主色调较为明显,也便于测试~

获取图片数据 ????

我们知道图片是由一个个像素点组成的。通过 canvas 的getImageData()方法恰好可以获取图片的像素数据:

let imgObj = document.getElementById('yourId');// 创建画布
let canvas = document.createElement('canvas');
canvas.setAttribute('width', imgObj.width);
canvas.setAttribute('height', imgObj.height);
let context = canvas.getContext('2d');
// 将图片画在画布上
context.drawImage(imgObj, 0, 0);
// 获取像素数据
let imgData = context.getImageData(0, 0, imgObj.width, imgObj.height);
let pixelData = imgData.data;

但这时你去打印pixelData,你会发现结果为:好家伙,全是 0,,,????

我一时想不到是什么原因:难道是 canvas 的 api 使用不熟练?

stackoverflow上找到了上面的回答:但是我修改后还是不行。

这时,我想到图片加载是异步的。可能图片还没加载完毕就开始从画布读取图片数据了,显然这是不对的。于是我对原有代码做了一番调整:

getMainColor("./test.jpeg");
function getMainColor(image) {return new Promise((resolve, reject) => {try {const canvas = document.createElement("canvas");const img = new Image(); // 创建img元素img.src = image; // 设置图片源地址img.onload = () => {let color = getImageColor(canvas, img);resolve(color);};} catch (e) {reject(e);}});
}
function getImageColor(canvas, img) {const context = canvas.getContext("2d");context.drawImage(img, 0, 0);// 获取像素数据let pixelData = context.getImageData(0,0,canvas.width,canvas.height).data;console.log("pixelData", pixelData);return pixelData;
}

事实证明:it's true

获取了图片数据,下一步就要对其进行相应的处理。

对图片数据进行处理 ????

展开上一步得到的数据:这里的数据是什么意思呢?其实就是rgba,分布代表红色(Red)绿色(Green)蓝色(Blue)透明度(Alpha)rgba 的图片每个像素点是由上面四个数值表示的。也就是说每四个为一组。

知道了规律,那让我们来对数据做一下清洗:主要就是对颜色进行分组,并统计每种颜色分别出现的次数:

function getImageColor(canvas, img) {const context = canvas.getContext("2d");context.drawImage(img, 0, 0);// 获取像素数据let pixelData = context.getImageData(0,0,canvas.width,canvas.height).data;console.log("pixelData", pixelData);return getCountsArr(pixelData);
}
function getCountsArr(pixelData) {let colorList = [];let rgba = [];let rgbaStr = "";// 分组循环for (let i = 0; i < pixelData.length; i += 4) {rgba[0] = pixelData[i];rgba[1] = pixelData[i + 1];rgba[2] = pixelData[i + 2];rgba[3] = pixelData[i + 3];if (rgba.indexOf(undefined) !== -1 || pixelData[i + 3] === 0) {continue;}// console.log("rgba", rgba);rgbaStr = rgba.join(",");if (rgbaStr in colorList) {++colorList[rgbaStr];} else {colorList[rgbaStr] = 1;}}console.log("colorList", colorList);return colorList;
}

打印colorList结果为:

到这里,我们就得到了每种数据分别出现的次数。

对颜色列表排序 ????

最后一步,对上面得到的色值对象做一个排序:

for (let prop in colorList) {arr.push({// 如果只获取rgb,则为`rgb(${prop})`color: `rgba(${prop})`,count: colorList[prop],});
}
// 数组排序
arr.sort((a, b) => {return b.count - a.count;
});console.log("arr", arr);

排序后得到如下结果:

到这里我们就得到了图片色值出现次数从大到小的排序数组,我们来看排在第一位的rgba(206,205,201,255)再把测试图片贴一下:肉眼可见的主题色已经被提取出来了!????

反思 ????

最后还是回到文章最开始提到的网易云音乐的播放器特效。不管它的实现方式是怎么样的,它的这种产品创意是值得我们学习的。

我们平时在浏览国内外的一些网站或者使用一些 app 时,总能遇到一些让你拍手称赞的效果。而这些特效往往又与我们前端分不开。

俗话说:前端是离产品最近的开发工程师,那最近你有没有遇到一些让你感觉很惊艳或者很有想法的效果呢,欢迎在评论区留言 ????

关于奇舞团

奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。

如何对图片主题色进行提取相关推荐

  1. 基于QT和Node.js的八叉树算法提取图片主题色

    资源下载地址:https://download.csdn.net/download/sheziqiong/85883609 资源下载地址:https://download.csdn.net/downl ...

  2. 博客相关 | 如何获取图片主题色并修改字体颜色

    今天在写博客的时候,做了一个封面图,然后hexo cl && hexo g && gulp && hexo s一键生成,点开后却发现这个标题的字体颜色亮 ...

  3. Swift主题色顶级解决方案

    一.常规主题色使用点 应用在发布前都会对主题色进行设置,以统一应用的风格(可能有多套主题).在主题色设置上有几个方面,如下: 1. TabBar部分,设置图片高亮.文本高度颜色 2. Navigati ...

  4. 基于python的K-means聚类提取图片主色

    基于python+opencv的彩色图片主色提取--利用K-means聚类算法 一.K-means聚类算法 1.K-means算法原理 2. K-means聚类算法流程 3.sklearn库中skle ...

  5. python 3d绘图kmeans_Python爬虫与K-means聚类算法分析多数据图片主色方法

    玩蛇网python爬虫与数据分析,本文结合python爬虫与K-means算法的使用,来分析图片主基色.色彩斑斓的一张图片,哪种颜色是它的主色调呢?今天就来讲讲如何用Python爬虫与K-means聚 ...

  6. vue动态发布到线上_vue在线动态切换主题色方案

    主要原理是利用webpack插件webpack-theme-color-replacer提取相关颜色css然后根据配置动态生成替换的css 具体实现步骤如下: 1.添加webpack插件,新建文件we ...

  7. 独家 | 图片主题建模?为什么不呢?!

    作者:Maarten Grootendorst 翻译:陈超 校对:赵茹萱本文约3200字,建议阅读5分钟 本文介绍了使用图片主题进行建模. 主题建模是一种允许用户在无监督情况下,在海量数据当中寻找主题 ...

  8. ios设置tabbar背景颜色_WooCommerce微信小程序2.9.3版本发布 后台设置主题色 底栏装修定制...

    更新又来咯! 本次更新主要以配置小程序方面的体验优化为主 通过后台设置主题色 以往更换小程序的主题色,需要重新下载小程序,万一小程序已经改动过,下载后又要重新修改一次 本次更新后,主题色可直接在后台选 ...

  9. webpack插件实现自动抽取css中的主题色样式,并动态切换主题色(element-ui)

    项目项目中用了element-ui,有切换主题色的需要.但官方的方式,有几个问题: 1.需要下载整个element-ui的样式css,并替换其中的css样式颜色.文件较大,下载慢且影响性能. 2.只能 ...

最新文章

  1. .Net 文件流 System.IO之Stream
  2. 【深度学习】基于Colab Pro的TPU训练模型教程(Tensorflow)
  3. ASP.NET Core Web 应用程序系列(二)- 在ASP.NET Core中使用Autofac替换自带DI进行批量依赖注入(MVC当中应用)...
  4. linux命令编写四位数密码本,grub-crypt命令 – 对口令进行加密
  5. Android之 RecyclerView,CardView 详解和相对应的上拉刷新下拉加载
  6. vs不一致的行尾对话框怎么调出_SolidWorks工程图打开后图纸没有了空白了怎么办?还能找回来吗?...
  7. LeetCode 392 判断子序列
  8. Gdcm源码编译with python wrap详解
  9. Java多线程系列---“基础篇”08之 join()
  10. C#基础知识五之abstract virtual关键字
  11. JavaScript浏览器对象之window对象详解
  12. 抖音网页直播弹幕 protobuf 推导
  13. vue 高德地图 不同区域显示不同颜色_高德地图这样用成为你的图表神器
  14. 深入理解图优化与g2o:g2o篇
  15. autojs微信运动自动点赞
  16. 智能修改文案-智能写作平台
  17. 紧耦合LIO综述 | 6篇顶会论文看透紧耦合LIO玩儿法(LIOM/LIO-SAM)
  18. 摘-连载-《青青子衿》(念才)-采葛-96
  19. 基于eNSP的企业PON入云网络模拟
  20. 偷偷爆料下 955 不加班公司名单(2023 年最新版!)

热门文章

  1. 万字详解大数据平台异地多机房架构实践
  2. 前端初学者的痛,没学历没工作经验如何找工作?
  3. 小程序免官费注册和突破实名只能绑定5个小程序的限制
  4. 大学计算机基础b上机考试题目,大学计算机基础上机考试题库
  5. 成都物韵电子商务有限公司推广网店需要注意什么?
  6. Mysql数据库与数据库三大范式
  7. word中那些奇怪的数学符号字体是怎么打出来的
  8. Windows XP中手动安装驱动程序的方法
  9. windows桌面上自由添加自定义文字软件--BgInfo
  10. 互联网之父Vint Cerf确诊肺炎,曾获图灵奖和总统自由勋章