2017-05-11 26 views
2

我知道如何将CSS过滤器实际应用于图像的问题已被多次询问。有些答案并未实际使用CSS过滤器,但似乎仍能完成工作。不幸的是,我对JavaScript很陌生,我不明白这些答案。如何使用这些stackoverflow答案保存应用了过滤器的画布?

所以,我的问题是两个部分:

  1. 由于一些这些答案都老了,已经发展节能与CSS滤镜画布图像应用的一种方式?

  2. 如果不是,我该如何实现其中一个stackoverflow答案中描述的解决方案?我基本上需要一个实际应用多个滤镜到图像或像素的代码样本,这些代码样本并未包含在原始答案中。

谢谢

答案:

在第一个答案,我在圈失去的 “...”。在第二个答案,则对第4步没有详细信息,如果我是正确的,这两种使用CSS3过滤器,这是我的首选的:Capture/save/export an image with CSS filter effects applied

我迷失在这一个步骤3 :is anyone solve about saving filtered canvas as an image?

我再次失去了对非CSS滤镜的应用程序:How to save image from canvas with css filters

的JavaScript:

// I know I eventually need to move these globals so they're passed as parameters.   
    var image; 
    var c; 
    var context; 
    var file; 

    // Begin File Open Code. 
    function fileOpen() 
    { 
    var fileInput = document.getElementById('fileInput'); 
    var fileDisplayArea = document.getElementById('iDisplay'); 

    fileInput.addEventListener('change', function(e) 
    { 
     file = fileInput.files[0]; 
     var imageType = /image.*/; 
     if (file.type.match(imageType)) 
     { 
     var reader = new FileReader(); 
     reader.onload = function(e) 
     {     
      iDisplay.innerHTML = ""; 
      image = new Image(); 

      image.src = reader.result; 
      image.id = "I";    // Add an id attribute so the image editor code can access the image. // Image has since been moved to canvas. 
      iDisplay.appendChild(image); 
      image.onload = function() 
      { 
      c = document.getElementById("C"); 
      context = c.getContext("2d"); 
      c.width = image.width; 
      c.height = image.height; 
      context.drawImage(image,0,0); 
      }     
     } 
     reader.readAsDataURL(file); 
      } 
     else 
     { 
     iDisplay.innerHTML = "File type not supported." 
      } 
     }); 
    setValues(); // Call setValues() as function exits to set Image Editing Code Hue Slider to 0. 
    } 
    // End File Open Code 

    // Begin Image Editing Code. 
    var degrees = 0; 
    var percentB = 100; 
    var percentC = 100; 

    // Set initial values of sliders 
    function setValues() 
    {  
    form1.brightness.value = 100; 
    form1.contrast.value = 100; 
    form1.hue.value = 0;  
    } 

    // Get slider settings and apply changes to image 
    function apply() 
    { 
    degrees = form1.hue.value; 
    percentC = form1.contrast.value; 
    percentB = form1.brightness.value; 
    // This is the crux of my question: How do I apply this properly, using the stackoverflow answers, so that the edited image may be saved? 
    if (document.getElementById("C") != null) document.getElementById("C").style.filter = "brightness(" + parseInt(percentB) + "%)" + " contrast(" + parseInt(percentC) + "%)" + " hue-rotate(" + parseInt(degrees) + "deg)"; 
    if (document.getElementById("C") != null) document.getElementById("C").style.WebkitFilter = "brightness(" + parseInt(percentB) + "%)" + " contrast(" + parseInt(percentC) + "%)" + " hue-rotate(" + parseInt(degrees) + "deg)"; 
    } 
    // End Image Editing Code 

    // Canvas was not cooperating, it needed c.width not c.style.width, can probably remove these and replace with small default values.  
    function setCanvasWidth() 
    { 
    c.width = image.width; 
    } 

    function setCanvasHeight() 
    { 
    c.height = image.height; 
    } 

    // Begin File Save Code (or user can right click and save if filters get applied. 
    function save() 
    { 
    alert("Place file save code here.") 
    } 

HTML

<!doctype html> 
<html lang="en"> 
<head> 
    <title>HTML5 CSS3 Javascript Image Editor</title> 
    <meta charset="utf-8"/> 
    <link rel="stylesheet" type="text/css" href="default.css"/> 
    <script src="nav.js"></script> 
    <script type="text/javascript"> 
    // JavaScript is in here. 
    </script> 

<!-- style elements specific to this page are placed in the style tags. --> 
<style> 

    image 
    { 
    max-width: 100%; 
    display: block; 
    margin: auto; 
    margin-left: auto; 
    margin-right: auto; 
    } 

    #C 
    { 
    max-width: 100%; 
    display: block; 
    margin: auto;  
    left: 0; 
    right: 0; 
    margin-left: auto; 
    margin-right: auto; 
    } 

    #iDisplay 
    { 
    margin-top: 2em; 
    max-width: 100%; 
    overflow-x: auto; 
    margin-left: auto; 
    margin-right: auto; 
    display: none; 
    } 

</style> 
</head> 
    <body onload="setValues()"> 
<header> 
    <a href="index.html"><img src="logoglow.png" alt="Logo Image" width="215" height="135" /></a> 
    <a href="index.html"><img src="ac.png" alt="Header Image" width="800" height="135" /></a> 
</header> 
<main> 
    <h3>An Ongoing Experiment in HTML5/CSS3/JavaScript Image Editing</h3> 
    <div> 
    <!-- Nav is floating left and Main is floating right, clear float styles (IF NEEDED) so they dont interfere with new image. -->  
    <p style="float:left;"> 
    <input type="file" id="fileInput" onclick="fileOpen()"></p> 
    <br style="clear:both"> 
    </div> 
    <div id="iDisplay"></div> 
    <br style="clear:both"><br style="clear:both"> 
    <!-- <script>document.write('<img src="' + file + '"/>');</script><br><br> --> 
    <!-- <div style="overflow:scroll;"> --> 
    <canvas style="color:#FFFFFF;" id="C" width="javascript:setCanvasWidth()" height="javascript:setCanvasHeight()">Your browser is too old to support this feature. <br>Please consider updating to a modern browser.</canvas> 
    <!-- </div> --> 
    <!-- use javascript:function() to get width and height? --> 
    <div id="afterCanvas"> 
    <br><br> 
    <form name="form1" id="form1id" action="javascript:save();" style="font-size:90%; text-align:center;"> 
    Brightness: <input type="range" name="brightness" min="0" max="200" step="5" onmousemove="apply()" ontouchmove="apply()" style="vertical-align:-7px;" />&nbsp; &nbsp; 
    Contrast: <input type="range" name="contrast" min="0" max="200" step="5" onmousemove="apply()" ontouchmove="apply()" style="vertical-align:-7px;"/>&nbsp; &nbsp; 
    Hue: <input type="range" name="hue" min="0" max="360" step="5" onmousemove="apply()" ontouchmove="apply()" style="vertical-align:-7px;"/> 
    <br><br> 
    <input type="submit" style="float:left;" value="Save Changes" /> <!-- chnage to type="submit" if form action is needed --> 
    </form> 
    </div> 
</main> 
</body> 
</html> 
+0

我也许应该提到,5天之后,我的一切工作。除了我的问题中的问题。 – TonyLuigiC

回答

3

让我们来看看这本部分从你的问题,因为如果你只是支持的浏览器在那里工作的,这就是你需要:

同样,我失去了对非CSS滤镜的应用程序:How to save image from canvas with css filters

上下文的filter property作品就像CSS滤镜–需要ŧ他同样的功能–但重要的是要知道的是,不像CSS,应用过滤器的上下文确实而不是更改画布'当前图像。它仅适用于后续的绘图操作。

这里是一个例子。当你运行下面的代码片段时,你会看到两个画布。第一个应用了CSS filter,第二个没有(如第一个画布的边界模糊而呈粉红色,而第二个则是清晰和绿色的事实所证明的)。

当你再点击“复制图片”按钮,代码

  1. 看什么CSS滤镜目前适用于第一画布,
  2. 应用该过滤器值的第二方面,
  3. 将第一个画布绘制到第二个画布上。

由于2),3)中的绘图操作将应用过滤器。

第二个画布现在看起来像第一个画布,但第二个画布现在确实包含色相旋转和模糊的像素,而第一个画布仍然有红色和清晰的像素–您只是没有看到,因为CSS过滤器。

此时,您可以将第二张画布另存为图片,并且它看起来和预期的一样。

window.onload = function() { 
 
    var cnv1 = document.getElementById("canvas1"); 
 
    var ctx1 = cnv1.getContext("2d"); 
 
    
 
    var cnv2 = document.getElementById("canvas2"); 
 
    var ctx2 = cnv2.getContext("2d"); 
 
    
 
    ctx1.font = "30px sans-serif"; 
 
    ctx1.fillStyle = "red"; 
 
    ctx1.fillText("Hello world!", 30, 80); 
 

 
    var button = document.getElementById("button"); 
 
    button.onclick = function() { 
 
    
 
    // take whatever CSS filter is applied to the first canvas 
 
    var cssFilter = getComputedStyle(cnv1).filter; 
 
    
 
    // use that filter as the second canvas' context's filter 
 
    // all subsequent drawing operations will have this filter applied 
 
    ctx2.filter = cssFilter; 
 
    
 
    // take whatever is in canvas 1 and draw it onto canvas 2 
 
    // the text on cnv1 is red and un-blurred (it's only the css 
 
    // that makes it look otherwise), but the above filter will 
 
    // cause blurring and hue-shifting to be applied to the drawImage 
 
    // operation 
 
    ctx2.drawImage(cnv1, 0, 0); 
 
    }; 
 
}
* { 
 
    vertical-align: top; 
 
} 
 

 
canvas { 
 
    border: 2px solid green; 
 
} 
 
#canvas1 { 
 
    filter: blur(2px) hue-rotate(180deg); 
 
}
<canvas id="canvas1" width="200" height="200"></canvas> 
 

 
<canvas id="canvas2" width="200" height="200"></canvas> 
 

 
<button id="button">Copy image</button>

+0

我已经服用了一颗安眠药,现在无法实施和测试这种药物,但**非常感谢您抽出时间。一个后续问题从我的沉着头脑:如何将滑块(范围)值作为#canvas1中的变量添加?我确信我使用JavaScript来做这件事,但我不确定多个过滤器的语法。谢谢! – TonyLuigiC

+0

你应该能够重新使用你已有的代码。当用户改变这些值时,像你现在所做的那样,将值作为CSS'style'应用。只有当您想要保存图像时,才会创建第二个画布,并将其当前上下文中的任何CSS滤镜应用于其上下文。这就是'var cssFilter = getComputedStyle(cnv1).filter; ctx2.filter = cssFilter;'在我的例子中。然后复制图像('ctx2.drawImage(cnv1,0,0);')。 – ij6

+0

Canvas'ctx.filter'允许多个滤镜函数,就像CSS'filter'一样(请注意,我的示例同时使用了'blur'和'hue-rotate')。所以你不需要做任何特别的事情来支持它。 – ij6

相关问题