当前位置: 首页 > 知识库问答 >
问题:

javascript - 如何给canvas图片的轮廓描边?

小牛23084
2024-05-08

如图,如何给透明背景的canvas图片的轮廓描边。

尝试过几个方案,但是达不到想要的效果

共有1个答案

武彭薄
2024-05-08

要在Canvas上给图片轮廓描边,你可以使用CanvasRenderingContext2D API 的 stroke()beginPath() 方法。首先,你需要使用 getImageData() 来获取图片像素数据,然后根据这些像素数据绘制出轮廓。下面是一个简单的步骤指南和代码示例,它演示了如何实现这个功能:

步骤指南:

  1. 加载图片:使用 new Image() 创建一个新的图片对象,并设置其 src 属性为你的图片URL。
  2. 等待图片加载:在图片对象的 onload 事件处理器中执行描边操作。
  3. 获取Canvas上下文:使用 getContext('2d') 获取Canvas的2D渲染上下文。
  4. 绘制图片:使用 drawImage() 方法将图片绘制到Canvas上。
  5. 获取像素数据:使用 getImageData() 获取图片的像素数据。
  6. 遍历像素数据:遍历每个像素,找到边缘像素(即与其相邻像素颜色有显著差异的像素)。
  7. 描边:对于每个检测到的边缘像素,使用 beginPath()moveTo()/lineTo() 方法绘制轮廓。
  8. 设置线条样式:使用 strokeStylelineWidth 设置线条的颜色和宽度。
  9. 描边并清除:使用 stroke() 描边,然后使用 clearRect() 清除原始图片,只留下轮廓。

代码示例:

const canvas = document.querySelector('canvas'); // 获取canvas元素const ctx = canvas.getContext('2d'); // 获取2D渲染上下文const img = new Image(); // 创建新的图片对象img.onload = () => {  // 图片加载完成后执行的操作  canvas.width = img.width; // 设置canvas宽度  canvas.height = img.height; // 设置canvas高度    // 绘制图片  ctx.drawImage(img, 0, 0);    // 获取像素数据  const imageData = ctx.getImageData(0, 0, img.width, img.height);  const data = imageData.data;    // 遍历像素数据  for (let y = 0; y < img.height; y++) {    for (let x = 0; x < img.width; x++) {      const index = (y * img.width + x) * 4;      // 根据像素颜色判断是否为边缘像素(这里只是一个简单的示例,你可能需要更复杂的算法来检测边缘)      if (isEdgePixel(data, x, y, img.width)) {        // 如果是边缘像素,记录坐标        edgePoints.push({x, y});      }    }  }    // 描边  ctx.beginPath();  edgePoints.forEach((point, index) => {    if (index === 0) {      ctx.moveTo(point.x, point.y);    } else {      ctx.lineTo(point.x, point.y);    }  });  ctx.strokeStyle = 'black'; // 设置线条颜色  ctx.lineWidth = 5; // 设置线条宽度  ctx.stroke(); // 描边    // 清除原始图片  ctx.clearRect(0, 0, img.width, img.height);};img.src = 'path_to_your_image.png'; // 设置图片源路径// 边缘像素检测函数(这里只是一个简单的示例,你可能需要更复杂的算法)function isEdgePixel(data, x, y, width) {  const threshold = 50; // 设置颜色阈值  const index = (y * width + x) * 4;  const r = data[index];  const g = data[index + 1];  const b = data[index + 2];    // 检查当前像素及其相邻像素的颜色差异  const isEdge =     Math.abs(r - data[(y * width + Math.max(x - 1, 0)) * 4]) > threshold ||    Math.abs(g - data[(y * width + Math.max(x - 1, 0)) * 4 + 1]) > threshold ||    Math.abs(b - data[(y * width + Math.max(x - 1, 0)) * 4 + 2]) > threshold ||    // ... 添加更多相邻像素的检查 ...    ;    return isEdge;}
 类似资料:
  • 我有3个maven项目A、B、C。A是B的父项目,B是C的父项目。所有概要文件都在pom中定义。项目A的xml。 在项目C中,我试图根据所选概要文件在spring测试上下文中选择属性文件(在src/test/resources下)。对于回归测试,我们有两个属性文件: 本地应用程序测试。属性 在我们的Windows开发系统上,选定的配置文件将是“本地”的,相应地在服务器上也是如此。选择“本地”配置文

  • 基本上,我试图用一种颜色画出第一个轮廓。但此程序崩溃,出现以下错误: 09-11 09:56:38.390:D/DalvikVM(1920):GC_FOR_ALLOC释放170K,10%释放3702K/4100K,暂停4ms,共4ms 09-11 09:56:38.420:E/CV::error()(1920):OpenCV error:cv::mat cv::cvarrtomat(const C

  • 图表的文本数据本来是一层白色的轮廓的,因为图表底色是白色的,因此在 canvas 下看不到这个轮廓。但是转化为视频后,会在这个白色的轮廓的最外边缘多出黑色的边缘,导致轮廓在视频中可以看到。请问一下为什么转化为视频后轮廓外沿会有黑影?而且如果把 label 的 textBorderColor 设置为 'black',就会消除这个黑影,而设置 textBorderWidth 为 0 并不会消除这个黑影

  • 主要内容:1. outline-style,2. outline-width,3. outline-color,4. outline,5. outline-offset轮廓(outline)是绘制于元素周围的一条线,位于边框的外围(紧贴着边框),主要用来突出显示某个元素,如下图所示: 图:轮廓(outline) 轮廓和边框看起来非常相似,但它们之间也并非没有区别,例如: 元素上下左右四个方向上边框的样式、宽度、颜色可以单独设置,而轮廓在元素四个方向的宽度、样式、颜色都是相同的,不能单独设置; 边

  • 我有2个URL,其中1个特定于Dev,另一个特定于Prod。我也在使用Spring profiling,其中我有一个单独的文件用于Dev和Prod application-Dev。性能和应用-prod。属性和我的应用。对于Dev env,属性文件如下所示 spring.profiles.active=dev 现在在我的java代码中,我想有一个属性,它将根据我使用的Spring配置文件绑定到适当的

  • 问题内容: 有没有一种简单的方法来获取绘制如下轮廓线的(x,y)值: 问题答案: 查看返回的ContourSet的collections属性。特别是第一个集合的get_paths()方法返回组成每个线段的成对点。 要获取坐标的NumPy数组,请使用属性。