gpt4 book ai didi

javascript - 如何使用 JavaScript 为特殊过滤器在 html Canvas 中绘制图像

转载 作者:太空宇宙 更新时间:2023-11-04 06:09:30 26 4
gpt4 key购买 nike

我已经成功地将 CSS 铅笔效果应用到这张很棒的 site 的图像上。 .我需要在 HTML Canvas 中使用 JavaScript drawImage 复制效果。

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

任何工作片段都非常有用。

谢谢!

//  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)
}
@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);
}
}
<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>

最佳答案

您可以通过 2D 上下文 API 逐步重现您的 CSS 正在执行的操作来实现相同的效果。

第一步是绘制偏移量为-1 -1 的图像(第一个背景图像)。这可以通过使用 drawImage() 轻松实现。 .

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";
<canvas id="canvas" style="background: red"></canvas>

第二步是将此图像与其自身的副本混合,并在另一个方向稍微偏移。
difference 混合模式也可通过其 globalCompositeOperation 在 2d 上下文 API 中使用。属性:

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";
<canvas id="canvas" style="background: red"></canvas>

最后一步是在这个混合图像上应用 CSS 过滤器 brightness(2) invert(1) grayscale(1)
再一次,2D 上下文 API 可以通过它的 filter 来做到这一点。属性(property)。

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";
<canvas id="canvas" style="background: red"></canvas>

关于javascript - 如何使用 JavaScript 为特殊过滤器在 html Canvas 中绘制图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56542376/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com