js实现任意更改base64字符串图片的颜色,封装函数

背景

开发echarts时,通过base64字符串设置markPoint自定义图标,但是如果颜色有所变更,就很麻烦了,就研究下了下如何给base64字符串转颜色

js 复制代码
  markPoint: {
              symbol:
                'image://' +                
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEUAAAAjCAMAAAD1/jdcAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAALFQTFRFAAAA661F661F661F661F661F661F661F661F661F661F661F661F661F7bNR8Lxi8b5m8b9n661F661F661F8b5l661F661F661F661F8b5m8b9m7bNR661F7LFM661F661F661F7bRS8b5m8L1k7LBK661F661F661F661F661F661F7rVT8L1k7LBL661F661F661F661F7rZV8L1k7LFN661F661F661F661F661FvQ/oBwAAADt0Uk5TAAIHDBIVFgQcLTk/QSNbzvb/Bg0s7jgRPhT391obTSJDS3/45mVJQgMXHTFz5FUrARAoZNJHDhkeCwVXmKGrAAAA40lEQVR4nO3WxxKCMBAG4IWlg8QgRQTE3nvX938wE73KOJN48MB/znzZ0/4LAIqKmm6IRddQVYDFRMt2XE8srmNbaLJJsOGTJhVNk/gNVEC1fHHj5fhWAC2bSCGUkhBBc+RGoTSKE9BdSYTSdgqGJ614Rq3USq3Uyp8rP9iYbsq2d0cS4dv7N03CWi2TQrK8CHjD5iQSNiLSLVnD8rYP449t3+sPhuzhaDyZVrZ9HBY440eDElRcHvPFcpXR9WZbVF8eCQavy6M6O3N/OJ7O5fsz4ezMy/Vm3OUQxswe6uPLxDxPYLiMPmJuVccAAAAASUVORK5CYII',
              symbolSize: [65, 31],
              symbolOffset: [0, -22],
              label: {
                color: '#fff',
              },
              data: item.val.map((subitem, index) => {
                return { coord: [index, subitem], value: subitem };
              }),
            },

可运行的完整html

思路:通过base64设置canvas上,更改canvas三原色,再canvas转base64

html 复制代码
<!DOCTYPE html>
<html>
  <head>
    <title>修改 Base64 图片颜色</title>
  </head>
  <body>
    <h1>修改 Base64 图片颜色</h1>
    <label for="base64Input">输入 Base64 字符串:</label>
    <textarea id="base64Input" rows="25" cols="220"></textarea><br />
    <label for="colorInput"
      >输入颜色(例如:#FF0000 或 rgb(255, 0, 0)):</label
    >
    <input type="text" id="colorInput" /><br />
    <button onclick="modifyImageColor()">修改颜色</button>
    <h2>修改后的图片:</h2>
    <img id="modifiedImage" src="" alt="Modified Image" />
    <button onclick="copyToClipboard()">复制修改后的 Base64</button>
    <script>
      function modifyImageColor() {
        const base64Image = document.getElementById("base64Input").value;
        const colorInput = document.getElementById("colorInput").value;
        const img = new Image();
        img.onload = function () {
          const canvas = document.createElement("canvas");
          canvas.width = img.width;
          canvas.height = img.height;
          const ctx = canvas.getContext("2d");
          ctx.drawImage(img, 0, 0);
          const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
          const pixels = imageData.data;
          let red = 0;
          let green = 0;
          let blue = 0;
          // 解析颜色输入
          if (/^#[0-9A-Fa-f]{6}$/.test(colorInput)) {
            red = parseInt(colorInput.substring(1, 3), 16);
            green = parseInt(colorInput.substring(3, 5), 16);
            blue = parseInt(colorInput.substring(5, 7), 16);
          } else if (
            /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/.test(colorInput)
          ) {
            const match = colorInput.match(
              /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/
            );
            red = parseInt(match[1]);
            green = parseInt(match[2]);
            blue = parseInt(match[3]);
          }
          for (let i = 0; i < pixels.length; i += 4) {
            pixels[i] = red; // 红色通道
            pixels[i + 1] = green; // 绿色通道
            pixels[i + 2] = blue; // 蓝色通道
          }
          ctx.putImageData(imageData, 0, 0);
          const newBase64Image = canvas.toDataURL("image/png");
          // 显示修改后的图片
          const modifiedImage = document.getElementById("modifiedImage");
          modifiedImage.src = newBase64Image;

          // 将修改后的 base64 图像保存到全局变量
          window.modifiedBase64Image = newBase64Image;
        };

        img.src = base64Image;
      }

      function copyToClipboard() {
        if (window.modifiedBase64Image) {
          const dummyTextArea = document.createElement("textarea");
          dummyTextArea.value = window.modifiedBase64Image;
          document.body.appendChild(dummyTextArea);
          dummyTextArea.select();
          document.execCommand("copy");
          document.body.removeChild(dummyTextArea);
          alert("修改后的 Base64 图像已复制到剪贴板!");
        } else {
          alert("请先点击 '修改颜色' 以生成修改后的 Base64 图像。");
        }
      }
    </script>
  </body>
</html>

封装base64字符串转颜色函数

js 复制代码
 modifyImageColor(base64Image, colorInput) {
      return new Promise((resolve, reject) => {
        const img = new Image();
        img.src = base64Image;
        img.onload = function () {
          const canvas = document.createElement('canvas');
          canvas.width = img.width;
          canvas.height = img.height;
          const ctx = canvas.getContext('2d');
          ctx.drawImage(img, 0, 0);
          const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
          const pixels = imageData.data;
          let red = 0;
          let green = 0;
          let blue = 0;
          // 解析颜色输入
          if (/^#[0-9A-Fa-f]{6}$/.test(colorInput)) {
            red = parseInt(colorInput.substring(1, 3), 16);
            green = parseInt(colorInput.substring(3, 5), 16);
            blue = parseInt(colorInput.substring(5, 7), 16);
          } else if (
            /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/.test(colorInput)
          ) {
            const match = colorInput.match(
              /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/
            );
            red = parseInt(match[1]);
            green = parseInt(match[2]);
            blue = parseInt(match[3]);
          }
          for (let i = 0; i < pixels.length; i += 4) {
            pixels[i] = red; // 红色通道
            pixels[i + 1] = green; // 绿色通道
            pixels[i + 2] = blue; // 蓝色通道
          }
          ctx.putImageData(imageData, 0, 0);
          const newBase64Image = canvas.toDataURL('image/png');
          resolve(newBase64Image);
        };
        img.onerror = function (error) {
          reject(error);
        };
      });
    },
js 复制代码
 ...
markPoint: {
              symbol:
                'image://' +
                (await this.modifyImageColor(
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEUAAAAjCAMAAAD1/jdcAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAALFQTFRFAAAA661F661F661F661F661F661F661F661F661F661F661F661F661F7bNR8Lxi8b5m8b9n661F661F661F8b5l661F661F661F661F8b5m8b9m7bNR661F7LFM661F661F661F7bRS8b5m8L1k7LBK661F661F661F661F661F661F7rVT8L1k7LBL661F661F661F661F7rZV8L1k7LFN661F661F661F661F661FvQ/oBwAAADt0Uk5TAAIHDBIVFgQcLTk/QSNbzvb/Bg0s7jgRPhT391obTSJDS3/45mVJQgMXHTFz5FUrARAoZNJHDhkeCwVXmKGrAAAA40lEQVR4nO3WxxKCMBAG4IWlg8QgRQTE3nvX938wE73KOJN48MB/znzZ0/4LAIqKmm6IRddQVYDFRMt2XE8srmNbaLJJsOGTJhVNk/gNVEC1fHHj5fhWAC2bSCGUkhBBc+RGoTSKE9BdSYTSdgqGJ614Rq3USq3Uyp8rP9iYbsq2d0cS4dv7N03CWi2TQrK8CHjD5iQSNiLSLVnD8rYP449t3+sPhuzhaDyZVrZ9HBY440eDElRcHvPFcpXR9WZbVF8eCQavy6M6O3N/OJ7O5fsz4ezMy/Vm3OUQxswe6uPLxDxPYLiMPmJuVccAAAAASUVORK5CYII',
                  '#4BC5F2'
                )),
              symbolSize: [65, 31],
              symbolOffset: [0, -22],
              label: {
                color: '#fff',
              },
              data: item.val.map((subitem, index) => {
                return { coord: [index, subitem], value: subitem };
              }),
            },
相关推荐
jin12332242 分钟前
基于React Native鸿蒙跨平台地址管理是许多电商、外卖、物流等应用的重要功能模块,实现了地址的添加、编辑、删除和设置默认等功能
javascript·react native·react.js·ecmascript·harmonyos
2501_920931701 小时前
React Native鸿蒙跨平台医疗健康类的血压记录,包括收缩压、舒张压、心率、日期、时间、备注和状态
javascript·react native·react.js·ecmascript·harmonyos
落霞的思绪1 小时前
配置React和React-dom为CDN引入
前端·react.js·前端框架
Hacker_Z&Q1 小时前
CSS 笔记2 (属性)
前端·css·笔记
Anastasiozzzz1 小时前
LeetCode Hot100 295. 数据流的中位数 MedianFinder
java·服务器·前端
橙露2 小时前
React Hooks 深度解析:从基础使用到自定义 Hooks 的封装技巧
javascript·react.js·ecmascript
Exquisite.2 小时前
Nginx
服务器·前端·nginx
2501_920931702 小时前
React Native鸿蒙跨平台使用useState管理健康记录和过滤状态,支持多种健康数据类型(血压、体重等)并实现按类型过滤功能
javascript·react native·react.js·ecmascript·harmonyos
打小就很皮...2 小时前
dnd-kit 实现表格拖拽排序
前端·react.js·表格拖拽·dnd-kit
Ulyanov2 小时前
从静态到沉浸:打造惊艳的Web技术发展历程3D时间轴
前端·javascript·html5·gui开发