首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在html画布中使用JavaScript为特殊过滤器绘制图像

如何在html画布中使用JavaScript为特殊过滤器绘制图像
EN

Stack Overflow用户
提问于 2019-06-11 11:08:37
回答 1查看 1.1K关注 0票数 0

我已经成功地应用CSS铅笔效果从这个伟大的站点图像。我需要在HTML中使用JavaScript drawImage复制效果。

上下文(CanvasRenderingContext2D)使用filter属性绘制图像,但我无法设置为上下文背景大小、背景图像、背景混合模式、背景位置。我需要最后过滤的图像保存在数据库中。图像处理必须在浏览器上,而不是服务器端.

任何有用的片段都是非常有用的。

谢谢!

代码语言:javascript
复制
//  Must be onload, otherwise canvas is not ready
window.onload = function() {

    let imageWidth = 800
    let imageHeight = 600

    let canvas = document.getElementById("canvas")
    canvas.width = imageWidth
    canvas.height = imageHeight

    let context = canvas.getContext("2d");
    let img = new Image() 
    img.width = imageWidth
    img.height = imageHeight
    img.src = "https://bennettfeely.com/image-effects/css/photo.jpg"

    let cssfilter = "brightness(2) invert(1) grayscale(1)" 
    context.filter = cssfilter 
          
    /*
    // Tried, but it does not work
    img.style.backgroundSize = "cover"
    img.style.backgroundImage = "url('https://bennettfeely.com/image-effects/css/photo.jp'), url('https://bennettfeely.com/image-effects/css/photo.jp')"
    img.style.backgroundPosition = "calc(50% - 1px) calc(50% - 1px), calc(50% + 1px) calc(50% + 1px)"
  
    // img.style = "background-blend-mode: difference; background-position: calc(50% - 1px) calc(50% - 1px), calc(50% + 1px) calc(50% + 1px); filter: brightness(2) invert(1) grayscale(1); box-shadow: inset 0 0 0 1px black;"
            */

    // Draw image
    context.drawImage(img, 0, 0, imageWidth, imageHeight)
}
代码语言:javascript
复制
@supports (filter: invert(1)) and (background-blend-mode: difference) {
    .pencil-effect {
        background-size: cover;
        background-image: url("https://bennettfeely.com/image-effects/css/photo.jpg"), url("https://bennettfeely.com/image-effects/css/photo.jpg");
        background-blend-mode: difference;
        background-position: calc(50% - 1px) calc(50% - 1px), calc(50% + 1px) calc(50% + 1px);
        filter: brightness(2) invert(1) grayscale(1);
    }
}
代码语言:javascript
复制
<img id="original-img" src="https://bennettfeely.com/image-effects/css/photo.jpg" width="800" height="600">
<img class="pencil-effect" width="800" height="600">
<canvas id="canvas" style="background: red"></canvas>

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-12 01:29:41

通过一步一步地再现CSS正在做的事情,您可以从2D上下文API中获得同样的效果。

第一步是绘制偏移量为-1 -1的图像(第一个背景图像)。使用drawImage()可以很容易地实现这一点。

代码语言:javascript
复制
const img = new Image();
img.onload = function() {
  const imageWidth = 800
  const imageHeight = 600
  const canvas = document.getElementById("canvas");
  canvas.width = imageWidth;
  canvas.height = imageHeight;
  const context = canvas.getContext("2d");

// first pass without any filter nor blending
  // simple offset
  context.drawImage(img, -1, -1, imageWidth, imageHeight)
};
img.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Point_Reyes_Lighthouse_%28April_2012%29.jpg/593px-Point_Reyes_Lighthouse_%28April_2012%29.jpg";
代码语言:javascript
复制
<canvas id="canvas" style="background: red"></canvas>

第二步是将该图像与其自身的副本进行混合,并在另一个方向上略有偏移。

difference混合模式也可以通过其globalCompositeOperation属性在2d上下文API中使用:

代码语言:javascript
复制
const img = new Image();
img.onload = function() {
  const imageWidth = 800
  const imageHeight = 600
  const canvas = document.getElementById("canvas");
  canvas.width = imageWidth;
  canvas.height = imageHeight;
  const context = canvas.getContext("2d");

// first pass without any filter nor blending
  // simple offset
  context.drawImage(img, -1, -1, imageWidth, imageHeight)
// second pass, do the blending without filter
  context.globalCompositeOperation = 'difference';
  // note how we draw the canvas over itself with the counter offset
  context.drawImage(img, 1, 1, imageWidth, imageHeight);
};
img.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Point_Reyes_Lighthouse_%28April_2012%29.jpg/593px-Point_Reyes_Lighthouse_%28April_2012%29.jpg";
代码语言:javascript
复制
<canvas id="canvas" style="background: red"></canvas>

最后一步是在这个混合图像上应用CSS-filter brightness(2) invert(1) grayscale(1)

再一次,2D上下文API可以通过它的filter属性来完成它。

代码语言:javascript
复制
const img = new Image();
img.onload = function() {
  const imageWidth = 800
  const imageHeight = 600
  const canvas = document.getElementById("canvas");
  canvas.width = imageWidth;
  canvas.height = imageHeight;
  const context = canvas.getContext("2d");
  const cssfilter = "brightness(2) invert(1) grayscale(1)" 

// first pass without any fiter nor blending
  // simple offset
  context.drawImage(img, -1, -1, imageWidth, imageHeight)
// second pass, do the blending without filter
  context.globalCompositeOperation = 'difference';
  // note how we draw the canvas over itself with the counter offset
  context.drawImage(img, 1, 1, imageWidth, imageHeight);

// third pass, apply the filter on the blended result
  context.filter = cssfilter;
  // since there is no transparency we could also have set it to 'source-over'
  context.globalCompositeOperation = 'copy';
  // here we don't set any offset: we only apply the filter
  context.drawImage(context.canvas, 0, 0, imageWidth, imageHeight)
};
img.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Point_Reyes_Lighthouse_%28April_2012%29.jpg/593px-Point_Reyes_Lighthouse_%28April_2012%29.jpg";
代码语言:javascript
复制
<canvas id="canvas" style="background: red"></canvas>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56542376

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档