IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    简单实现提取封面图片主题色作为博客主题色

    JayHrn发表于 2023-12-19 09:35:28
    love 0

    对于提取主题色,看过生成封面图片主色来作为文章封面顶图的文章,了解了许多,但是由于没有备案等,许多东西都没有办法使用,所以之内另寻他路了。无意中看到了一篇帖子是关于这个的,于是便根据这个,加上Heo的教程,便解决了这个问题。

    引入工具

    在使用这个功能之前,就需要引入js了,其实在GitHub上有许多的关于提取图片主题色的项目,但是好像就rgbaster使用的比较好,对于颜色提取更加准确。这里给出地址,大家可以自行看下。

    引用站外地址
    提取图片主题色
    briangonzalez

    使用这个我们需要引入js,新建themes/butterfly/source/js/rgbaster.min.js

    1
    !function(n){"use strict";var t=function(){return document.createElement("canvas").getContext("2d")},e=function(n,e){var a=new Image,o=n.src||n;"data:"!==o.substring(0,5)&&(a.crossOrigin="Anonymous"),a.onload=function(){var n=t("2d");n.drawImage(a,0,0);var o=n.getImageData(0,0,a.width,a.height);e&&e(o.data)},a.src=o},a=function(n){return["rgb(",n,")"].join("")},o=function(n){return n.map(function(n){return a(n.name)})},r=5,i=10,c={};c.colors=function(n,t){t=t||{};var c=t.exclude||[],u=t.paletteSize||i;e(n,function(e){for(var i=n.width*n.height||e.length,m={},s="",d=[],f={dominant:{name:"",count:0},palette:Array.apply(null,new Array(u)).map(Boolean).map(function(){return{name:"0,0,0",count:0}})},l=0;i>l;){if(d[0]=e[l],d[1]=e[l+1],d[2]=e[l+2],s=d.join(","),m[s]=s in m?m[s]+1:1,-1===c.indexOf(a(s))){var g=m[s];g>f.dominant.count?(f.dominant.name=s,f.dominant.count=g):f.palette.some(function(n){return g>n.count?(n.name=s,n.count=g,!0):void 0})}l+=4*r}if(t.success){var p=o(f.palette);t.success({dominant:a(f.dominant.name),secondary:p[0],palette:p})}})},n.RGBaster=n.RGBaster||c}(window);

    在你的主题文件中,引入该文件

    1
    2
    3
    4
    5
    6
    inject:
    head:
    # - <link rel="stylesheet" href="">

    bottom:
    + - <script src="/js/rgbaster.min.js"></script>

    使用

    对于使用,就是调用这个js,然后根据提取出来的图片设置博客的主题色就可以了,但是由于图片提取出来的颜色可能会太浅等原因,需要特殊处理下。对于里面的addRule设置变量颜色需要自行去修改。

    引入如下自定义js,你可以选择新建一个自定义的js文件,也可以在自己原本的自定义文件中使用。对于引入的文件需要保证在引入上述文件之后引入。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    // 封面纯色
    function coverColor() {
    var path = document.getElementById("post-cover")?.src;
    if (path !== undefined) {
    RGBaster.colors(path, {
    paletteSize: 30,
    exclude: ["rgb(255,255,255)", "rgb(0,0,0)", "rgb(254,254,254)"],
    success: function (t) {
    if (t.dominant != 'rgb(66,90,239)') {
    const c = t.dominant.match(/\d+/g);
    var value = `rgb(${c[0]},${c[1]},${c[2]})`;
    if (getContrastYIQ(colorHex(value)) == "light") {
    value = LightenDarkenColor(colorHex(value), -40)
    }
    document.styleSheets[0].addRule(':root', '--Jay-main:' + value + '!important');
    document.styleSheets[0].addRule(':root', '--Jay-main-op:' + value + '23!important');
    document.styleSheets[0].addRule(':root', '--Jay-main-op-deep:' + value + 'dd!important');
    document.styleSheets[0].addRule(':root', '--Jay-main-none:' + value + '00!important');
    Jay.initThemeColor()
    document.getElementById("coverdiv").classList.add("loaded");
    }
    }
    });

    } else {
    document.styleSheets[0].addRule(':root', '--Jay-main: var(--Jay-theme)!important');
    document.styleSheets[0].addRule(':root', '--Jay-main-op: var(--Jay-theme-op)!important');
    document.styleSheets[0].addRule(':root', '--Jay-main-op-deep:var(--Jay-theme-op-deep)!important');
    document.styleSheets[0].addRule(':root', '--Jay-main-none: var(--Jay-theme-none)!important');
    Jay.initThemeColor()
    }
    }

    // RGB颜色转化为16进制颜色
    function colorHex(str) {
    var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
    var that = str;
    if (/^(rgb|RGB)/.test(that)) {
    var aColor = that.replace(/(?:\(|\)|rgb|RGB)*/g, "").split(",");
    var strHex = "#";
    for (var i = 0; i < aColor.length; i++) {
    var hex = Number(aColor[i]).toString(16);
    if (hex === "0") {
    hex += hex;
    }
    strHex += hex;
    }
    if (strHex.length !== 7) {
    strHex = that;
    }
    return strHex;
    } else if (reg.test(that)) {
    var aNum = that.replace(/#/, "").split("");
    if (aNum.length === 6) {
    return that;
    } else if (aNum.length === 3) {
    var numHex = "#";
    for (var i = 0; i < aNum.length; i += 1) {
    numHex += (aNum[i] + aNum[i]);
    }
    return numHex;
    }
    } else {
    return that;
    }
    }

    // 16进制颜色转化为RGB颜色
    function colorRgb(str) {
    var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
    var sColor = str.toLowerCase();
    if (sColor && reg.test(sColor)) {
    if (sColor.length === 4) {
    var sColorNew = "#";
    for (var i = 1; i < 4; i += 1) {
    sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
    }
    sColor = sColorNew;
    }
    // 处理六位的颜色值
    var sColorChange = [];
    for (var i = 1; i < 7; i += 2) {
    sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));
    }
    return "rgb(" + sColorChange.join(",") + ")";
    } else {
    return sColor;
    }
    }

    // 变暗变亮主方法
    function LightenDarkenColor(col, amt) {
    var usePound = false;

    if (col[0] == "#") {
    col = col.slice(1);
    usePound = true;
    }

    var num = parseInt(col, 16);

    var r = (num >> 16) + amt;

    if (r > 255) r = 255;
    else if (r < 0) r = 0;

    var b = ((num >> 8) & 0x00FF) + amt;

    if (b > 255) b = 255;
    else if (b < 0) b = 0;

    var g = (num & 0x0000FF) + amt;

    if (g > 255) g = 255;
    else if (g < 0) g = 0;


    return (usePound ? "#" : "") + String("000000" + (g | (b << 8) | (r << 16)).toString(16)).slice(-6);
    }

    // 判断是否为亮色
    function getContrastYIQ(hexcolor) {
    var colorrgb = colorRgb(hexcolor);
    var colors = colorrgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
    var red = colors[1];
    var green = colors[2];
    var blue = colors[3];
    var brightness;
    brightness = (red * 299) + (green * 587) + (blue * 114);
    brightness = brightness / 255000;
    if (brightness >= 0.5) {
    return "light";
    } else {
    return "dark";
    }
    }
    coverColor()

    由于此代码是根据本人博客结构实现的,不一定在您的博客上可以生效,如果有什么问题,相信您可以自行调试成功解决。



沪ICP备19023445号-2号
友情链接