Нарисуйте пунктирную рамку/контур вокруг непрозрачной части изображения на холсте

Я рисую изображение на холсте и пытаюсь применить красный пунктирный контур толщиной примерно 2 пикселя, но в итоге получается сплошной красный контур. Исходное изображение представляет собой изображение в формате PNG с верхним и нижним текстом как часть изображения, как показано в следующем примере.

Белый медведь с текстом сверху и снизу.
Нарисуйте пунктирную рамку/контур вокруг непрозрачной части изображения на холсте

Я использую следующую функцию для создания красного контура:

import { saveAs } from 'file-saver';
export const genOutline = (
  imgSrc
) => {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  const refImage = new Image();
  refImage.src = imgSrc;
  refImage.style.width = "max-content";
  refImage.style.height = "max-content";
  refImage.onload = () => {
    //define hight and width of the canvas
    canvas.width = refImage.width + 30;
    canvas.height = refImage.height + 30;

    var dArr = [-1, -1, 0, -1, 1, -1, -1, 0, 1, 0, -1, 1, 0, 1, 1, 1], // offset array
      s = 2,  // thickness scale
      i = 0,  // iterator
      x = 5,  // final position
      y = 5;

    // draw images at offsets from the array scaled by s
    for (; i < dArr.length; i += 2) {
      ctx.drawImage(refImage, x + dArr[i] * s, y + dArr[i + 1] * s);
    }

    // fill with color
    ctx.globalCompositeOperation = "source-in";
    ctx.fillStyle = "red";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.

    // draw original image in normal mode
    ctx.globalCompositeOperation = "source-over";
    ctx.drawImage(refImage, x, y);

    canvas.toBlob((blob) => {
      console.info("blob", blob);
      saveAs(blob, "image_outlined.png");
      canvas.remove();
    });
  }
}

Но я хочу добиться чего-то похожего на то, что показано на следующем изображении:

Портрет девушки с текстом сверху и снизу и красным пунктирным контуром.
Нарисуйте пунктирную рамку/контур вокруг непрозрачной части изображения на холсте

Вы говорите, что у вас «получится сплошной красный контур». Можете ли вы показать нам этот код, тогда мы сможем помочь вам понять, как получить пунктирную линию вместо сплошной.

Ray Wallace 11.06.2024 20:54

Совсем не легко. Вам нужно найти крайний пиксель, а затем попиксельно отслеживать внешний край, пока он не вернется к начальному пикселю или не достигнет края холста. Это даст вам путь, к которому вы можете применить пунктирную линию. Используйте ctx.getImageData, чтобы получить данные пикселей.

Blindman67 12.06.2024 15:47
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В вашем коде я не вижу, чтобы вы что-нибудь пробовали с тире...
Вы можете делать тире с помощью setLineDash, вот два небольших примера.

class Shape {
  constructor(x, y, width, height, color, dashes) {
    this.color = color
    this.dashes = dashes 
    this.path = new Path2D();
    this.path.arc(x, y, height / 3, 0, Math.PI, true);
    this.path.rect(x + width / 2, y, -width, height);
  }

  draw(ctx) {
    ctx.beginPath();
    ctx.setLineDash(this.dashes);
    ctx.strokeStyle = this.color;
    ctx.stroke(this.path);
  }
}


var ctx = canvas.getContext("2d");
var shapes = [];
shapes.push(new Shape(30, 30, 50, 50, "blue", [3, 3]));
shapes.push(new Shape(95, 50, 40, 40, "red", [5, 5]));

shapes.forEach((s) => s.draw(ctx));
<canvas id = "canvas" width = "160" height = "160"></canvas>

const ctx = canvas.getContext("2d");
ctx.setLineDash([10,5])

function drawSpiral(x, y, radiusChange, maxRadius) {
  ctx.lineTo(x, y);
  var a = 0, r = radiusChange;
  while (r < maxRadius) {
    a += 1 / r * Math.PI;
    r = a * radiusChange;
    ctx.lineTo(x + Math.cos(a) * r, y + Math.sin(a) * r);
  }
  ctx.stroke();
}
drawSpiral(80, 80, 4, 80);
<canvas id = "canvas" width = "160" height = "160"></canvas>

Большая проблема заключается в том, чтобы сделать это вокруг контура изображения.
Ваше решение для контура заключалось в том, чтобы рисовать изображения со смещением, это не подходит для тире, вам действительно нужно получить истинный контур, а затем нарисовать его линиями.

Другие вопросы по теме