【问题标题】:How to cut a transparent hole into an image?如何将透明孔切割成图像?
【发布时间】:2017-08-09 10:07:03
【问题描述】:

我想从图像中切出一个洞(带有透明部分的 png)。背景有渐变。我首先尝试了 svg 和 mask 但这对我不起作用,因为孔中的渐变与外面的渐变同步。

Afaik atm 无法使用 svg 将透明孔切割成图像。 由于浏览器兼容性,无法使用 css 剪辑路径。

所以我决定切换到画布和 js。但只是在图像中画一个透明的圆圈是没有效果的。似乎必须有更高级的处理。

我对这个问题越来越绝望。任何帮助表示赞赏。

<!DOCTYPE html>
 <html>
 <head>
 <meta charset="UTF-8">
 <title>test - image processing</title>
 <script 
 src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
 </script>   
<style>
body{
  background: red;
  background: -webkit-linear-gradient(left top, red, yellow);
  background: -o-linear-gradient(bottom right, red, yellow);
  background: -moz-linear-gradient(bottom right, red, yellow);
  background: linear-gradient(to bottom right, red, yellow);
 }
 canvas{
   display: block;
   margin:100px auto;
   }
  </style>
</head>
  <body>
  <div class="canvas-wrapper">
   <canvas id="canvas" ></canvas>
  </div>
   <script>
   $(document).ready(function () {

    showImage();

    function showImage() {
      var ctx = document.getElementById('canvas').getContext('2d');
      var image = new Image();
      // adjust the image path
      image.src = 'yourImagePathHere';
      image.onload = function () {
        document.getElementById('canvas').width = image.width;
        document.getElementById('canvas').height = image.height;
        ctx.drawImage(image, 0, 0);

        var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);

        for (var i = 0; i < imgData.data.length; i += 4) {
          // how to process?
          imgData.data[i] = imgData.data[i];
          imgData.data[i + 1] = imgData.data[i+1];
          imgData.data[i + 2] = imgData.data[i+2];
          imgData.data[i + 3] = imgData.data[i+3];
        }

        ctx.putImageData(imgData, 0, 0);
      };
    }
  });
</script>

【问题讨论】:

标签: javascript svg


【解决方案1】:

我不理解您声称 SVG 不起作用的说法。使用 SVG,您所追求的似乎非常简单。

body{
  background: red;
  background: -webkit-linear-gradient(left top, red, yellow);
  background: -o-linear-gradient(bottom right, red, yellow);
  background: -moz-linear-gradient(bottom right, red, yellow);
  background: linear-gradient(to bottom right, red, yellow);
 }
<svg width="400" height="300">
  <defs>
    <mask id="hole">
      <rect width="100%" height="100%" fill="white"/>
      <rect x="200" y="100" width="100" height="100"/>
    </mask>
  </defs>
  
  <image width="400" height="300"
         xlink:href="http://placekitten.com/400/300"
         mask="url(#hole)"/>
</svg>

【讨论】:

  • 我在运行代码 sn-p 时没有看到圆圈被剪掉。
  • 这是因为 lorempixel.com 已关闭。我已将链接切换到另一个网站。
【解决方案2】:
<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>test - image processing</title>
  <script     
    src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
  </script>   
  <style>
   body{
    background: red;
    background: -webkit-linear-gradient(left top, red, yellow);
    background: -o-linear-gradient(bottom right, red, yellow);
    background: -moz-linear-gradient(bottom right, red, yellow);
    background: linear-gradient(to bottom right, red, yellow);
  }
  canvas{
   display: block;
   margin:100px auto;
  }
 </style>
</head>
<body>
 <div class="canvas-wrapper">
  <canvas id="canvas" ></canvas>
 </div>
 <script>
   $(document).ready(function () {

   showImage();

   function showImage() {
    var ctx = document.getElementById('canvas').getContext('2d');
    var image = new Image();
    // adjust the image path
    image.src = 'yourImagePathHere';
    image.onload = function () {
     document.getElementById('canvas').width = image.width;
     document.getElementById('canvas').height = image.height;
     ctx.drawImage(image, 0, 0);

     var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);

     for (var i = 0; i < imgData.data.length; i += 4) {
      // how to process?
      imgData.data[i] = imgData.data[i];
      imgData.data[i + 1] = imgData.data[i+1];
      imgData.data[i + 2] = imgData.data[i+2];
      imgData.data[i + 3] = imgData.data[i+3];
     }

      ctx.putImageData(imgData, 0, 0);
      // this line does the magic, have a look at Amadans link for further possibilities
      ctx.globalCompositeOperation='destination-out';
      // here starts the circle form which is cutted out
      ctx.beginPath();
      ctx.fillStyle='';
      ctx.arc(image.width/2,image.height/2,50,0,2*Math.PI);
      ctx.fill();
  };
 }
});
</script>

【讨论】:

  • 这将真正受益于一些随附的解释以及变成堆栈片段。 ctx.fillStyle='' 实现了什么?它会将其设置回默认值吗?
猜你喜欢
  • 1970-01-01
  • 2012-03-31
  • 2015-11-03
  • 1970-01-01
  • 1970-01-01
  • 2011-06-20
  • 1970-01-01
  • 2014-10-15
相关资源
最近更新 更多