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 };
              }),
            },
相关推荐
susu10830189111 分钟前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿1 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡2 小时前
commitlint校验git提交信息
前端
emmm4592 小时前
html兼容性问题处理
html
虾球xz3 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇3 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒3 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员3 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐3 小时前
前端图像处理(一)
前端
程序猿阿伟3 小时前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端