如何在Canvas的drawImage中修改SVG图片颜色及添加描边?
在Canvas中修改SVG颜色并添加描边的方法
方法1:修改SVG源码转为Data URL
直接修改SVG的填充、描边属性,再转为Data URL供Image对象使用,是最精准的方式。
假设你的exclamation-solid.svg源码如下:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"> <path d="M7.002 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0zM7.1 4.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 4.995z"/> </svg>
添加fill和stroke属性后转成Data URL:
const svgStr = ` <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"> <path fill="#ff0000" stroke="#000" stroke-width="0.5" d="M7.002 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0zM7.1 4.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 4.995z"/> </svg> `; const svgDataUrl = `data:image/svg+xml;base64,${btoa(svgStr)}`; const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); const img = new Image(); img.src = svgDataUrl; img.onload = () => ctx.drawImage(img, 0, 0, 12, 50);
如果SVG是外部文件,通过fetch加载并修改:
fetch("../images/exclamation-solid.svg") .then(res => res.text()) .then(svgText => { // 替换原有fill属性,添加stroke const modifiedSvg = svgText .replace(/fill="[^"]*"/g, 'fill="#ff0000"') .replace(/<path/g, '<path stroke="#000" stroke-width="0.5"'); const svgDataUrl = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(modifiedSvg)}`; const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); const img = new Image(); img.src = svgDataUrl; img.onload = () => ctx.drawImage(img, 0, 0, 12, 50); });
方法2:用Canvas全局合成模式修改颜色和添加描边
无需修改SVG源码,利用Canvas的合成模式实现颜色替换和描边。
修改填充色
import exclamationSolid from "../images/exclamation-solid.svg"; const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); const img = new Image(); img.src = exclamationSolid; img.onload = () => { // 绘制原始SVG ctx.drawImage(img, 0, 0, 12, 50); // 设置合成模式为source-in,仅在已有像素区域填充颜色 ctx.globalCompositeOperation = "source-in"; ctx.fillStyle = "#ff0000"; ctx.fillRect(0, 0, 12, 50); // 恢复默认合成模式 ctx.globalCompositeOperation = "source-over"; };
添加描边
通过绘制放大的彩色版本作为描边,再叠加原始SVG:
import exclamationSolid from "../images/exclamation-solid.svg"; const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); const img = new Image(); img.src = exclamationSolid; img.onload = () => { // 绘制放大的黑色描边(偏移1px,尺寸放大2px) ctx.drawImage(img, -1, -1, 14, 52); ctx.globalCompositeOperation = "source-in"; ctx.fillStyle = "#000"; ctx.fillRect(-1, -1, 14, 52); ctx.globalCompositeOperation = "source-over"; // 绘制原始尺寸的红色填充SVG ctx.drawImage(img, 0, 0, 12, 50); ctx.globalCompositeOperation = "source-in"; ctx.fillStyle = "#ff0000"; ctx.fillRect(0, 0, 12, 50); ctx.globalCompositeOperation = "source-over"; };
方法3:用Canvas滤镜实现描边和颜色修改
利用drop-shadow滤镜模拟描边,结合合成模式修改填充色:
import exclamationSolid from "../images/exclamation-solid.svg"; const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); const img = new Image(); img.src = exclamationSolid; img.onload = () => { // 用drop-shadow滤镜模拟描边,多次绘制增强效果 ctx.filter = "drop-shadow(0 0 1px #000)"; ctx.drawImage(img, 0, 0, 12, 50); ctx.drawImage(img, 0, 0, 12, 50); // 修改填充色 ctx.globalCompositeOperation = "source-in"; ctx.fillStyle = "#ff0000"; ctx.fillRect(0, 0, 12, 50); // 恢复默认设置 ctx.globalCompositeOperation = "source-over"; ctx.filter = "none"; };
内容的提问来源于stack exchange,提问作者whitebear
相关产品推荐
相关产品推荐

