簡體   English   中英

如何使用JavaScript將HTML畫布內的圖像繪制為特殊濾鏡

[英]How to draw an image inside a html canvas with JavaScript for special filters

我已經成功地將CSS鉛筆效果應用到了這個很棒的網站上的圖像 我需要在HTML畫布內使用JavaScript drawImage復制效果。

上下文(CanvasRenderingContext2D)使用filter屬性繪制圖像,但是我無法將上下文設置為background-size,background-image,background-blend-mode,background-position。 我需要將最終的過濾圖像保存在數據庫中。 圖像處理必須在瀏覽器上,而不是在服務器端。

任何有效的代碼段都非常有用。

謝謝!

 // 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> 

通過逐步重現CSS所做的工作,您可以從2D上下文API中獲得相同的效果。

第一步是以-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混合模式也可以通過2d上下文API中的globalCompositeOperation屬性來使用:

 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屬性來做到這一點。

 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> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM