首页 > 解决方案 > HTML5 Canvas - 为带有阴影的透明 png 添加边框

问题描述

在此画布脚本中,我仍在尝试解决两个问题,以使此图像具有我想要的外观。绿色仅用于演示。最终它将是带有灰色阴影的白色。

1)我想在图像获得绿色边框后为其添加灰色阴影。

2)我希望绿色边框的角是方形的,而不是圆形的。

在此处输入图像描述

var c = document.getElementById("canvas"),
    ctx = c.getContext("2d"),
    opaqueAlpha = 255,
    img = new Image();
    
img.onload = function(){
  ctx.shadowColor = '#0f0'; // green for demo purposes
  ctx.shadowBlur = 20;
  ctx.shadowOffsetX = 0;
  ctx.shadowOffsetY = 0;
  ctx.drawImage(img, 30, 30);
  
  img = ctx.getImageData(0, 0, ctx.canvas.width - 1, ctx.canvas.height - 1);
 
  // turn all non-transparent pixels to full opacity
  for (var i = img.data.length; i > 0; i -= 4) {
    if (img.data[i+3] > 0) {
      img.data[i+3] = opaqueAlpha;
    }
  }
 
  // write transformed opaque pixels back to image
  ctx.putImageData(img, 0, 0);
  
  // trying to get the img again and then apply the gray drop shadow...not working
  img = ctx.getImageData(0, 0, ctx.canvas.width - 1, ctx.canvas.height - 1);
  
  // need to add a gray shadow to the now opaque border
  ctx.shadowColor = '#aaa';
  ctx.shadowBlur = 10;
  ctx.shadowOffsetX = 0;
  ctx.shadowOffsetY = 0;
  ctx.putImageData(img, 0, 0);
};
img.setAttribute('crossOrigin', '');
img.src = "https://i.ezr.io/racks/bb0e6dd421df72541a79f271fb4f1a90.png?" + new Date().getTime();
<canvas id="canvas" width="800" height="800"></canvas>

标签: html5-canvas

解决方案


我会这样做:我知道图像的宽度和高度 ( img.width, img.height) 我也知道偏移量:30。您开始在距离原点 30 个单位的位置绘制图像。

由于这些区别看起来或多或少相同,我需要计算 3 个点才能知道如何绘制上凹口。

我希望这是你需要的:

var c = document.getElementById("canvas"),
  cw = (canvas.width = 750),
  ch = (canvas.height = 310),
  ctx = c.getContext("2d"),
  opaqueAlpha = 255,
  img = new Image();

img.onload = function() {
  let offset = 30;
  let whiteBorder = 15;

  ctx.drawImage(img, offset, offset);

  var imgData = ctx.getImageData(0, 0, cw, ch);
  var pixels = imgData.data;

  //get some points

  let y = offset + 5;
  let index = y * imgData.width * 4;

  let x1;
  for (let i = 0; i < imgData.width * 4; i += 4) {
    if (pixels[index + i + 3] > 0) {
      //console.log(i / 4);
      x1 = i / 4;
      break;
    }
  }

  let x2;
  for (let i = imgData.width * 4; i > 0; i -= 4) {
    if (pixels[index + i] > 0) {
      //console.log(i / 4);
      x2 = i / 4;
      break;
    }
  }

  let x = (offset + 5) * 4;
  let y1;
  for (let i = 0; i < imgData.height; i++) {
    if (pixels[i * imgData.width * 4 + x] > 0) {
      //console.log(i);
      y1 = i;
      break;
    }
  }
 

  // draw the border behind the image
  ctx.globalCompositeOperation='destination-over';
  ctx.beginPath();
  ctx.moveTo(offset, img.height + offset);
  ctx.lineTo(img.width + offset, img.height + offset);
  ctx.lineTo(img.width + offset, y1);
  ctx.lineTo(x2, y1);
  ctx.lineTo(x2, offset);
  ctx.lineTo(x1, offset);
  ctx.lineTo(x1, y1);
  ctx.lineTo(offset, y1);
  ctx.closePath();

  ctx.strokeStyle = "white";
  ctx.lineWidth = 25;
  ctx.stroke();


};
img.setAttribute("crossOrigin", "");
img.src =
  "https://i.ezr.io/racks/bb0e6dd421df72541a79f271fb4f1a90.png?" +
  new Date().getTime();
canvas{
filter:drop-shadow(0px 0px 5px #333);
}
<canvas id="canvas"></canvas>


推荐阅读