如何使用这些 stackoverflow 答案保存应用过滤器的 canvas?
How do I save a canvas with filters applied, using these stackoverflow answers?
我知道关于如何实际将 CSS 滤镜应用于图像的问题已被问过多次。给出的一些答案实际上并未使用 CSS 过滤器,但似乎仍能完成工作。不幸的是,我是 JavaScript 的新手,我不理解这些答案。
所以,我的问题分为两部分:
由于其中一些答案是旧的,是否已经开发出一种方法来保存应用了 CSS 滤镜的 canvas 图像?
如果没有,我该如何实施这些 Whosebug 答案之一中描述的解决方案?我本质上需要一个实际将多个过滤器应用于图像或像素的代码示例,原始答案中没有包含它。
谢谢
答案:
在第一个答案中,我迷失了循环中的“...”。在第二个答案中,没有关于步骤 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 Whosebug 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;" />
Contrast: <input type="range" name="contrast" min="0" max="200" step="5" onmousemove="apply()" ontouchmove="apply()" style="vertical-align:-7px;"/>
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>
让我们从你的问题来看这部分,因为如果你只支持它工作的浏览器,这就是你所需要的:
Again, I'm lost on the application of the non-CSS filters: How to save image from canvas with css filters
上下文的 filter
property 就像 CSS 过滤器一样工作 – 它具有相同的功能 – 但重要的是要知道,与 CSS 不同的是,将过滤器应用于context 不会 更改 canvas' current 图像。它仅适用于后续 绘图操作。
这是一个例子。当您 运行 下面的代码片段时,您会看到两个 canvas。第一个应用了 CSS filter
,第二个没有(第一个 canvas 的边框模糊且呈粉红色,而第二个清晰且清晰绿色)。
然后单击 "Copy image" 按钮时,代码
- 查看当前应用于第一个 canvas、
的 CSS 过滤器
- 将此过滤器值应用于第二个上下文,
- 将第一个 canvas 绘制到第二个上。
因为2),3)中的绘图操作会应用滤镜。
第二个 canvas 现在看起来像第一个,但是第二个 canvas 现在真正包含了色调旋转和模糊的像素,而第一个仍然有红色和清晰的像素 – 你只是因为 CSS 过滤器而看不到。
此时,您可以将第二个 canvas保存为图像,它看起来和预期的一样。
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>
我知道关于如何实际将 CSS 滤镜应用于图像的问题已被问过多次。给出的一些答案实际上并未使用 CSS 过滤器,但似乎仍能完成工作。不幸的是,我是 JavaScript 的新手,我不理解这些答案。
所以,我的问题分为两部分:
由于其中一些答案是旧的,是否已经开发出一种方法来保存应用了 CSS 滤镜的 canvas 图像?
如果没有,我该如何实施这些 Whosebug 答案之一中描述的解决方案?我本质上需要一个实际将多个过滤器应用于图像或像素的代码示例,原始答案中没有包含它。
谢谢
答案:
在第一个答案中,我迷失了循环中的“...”。在第二个答案中,没有关于步骤 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 Whosebug 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;" />
Contrast: <input type="range" name="contrast" min="0" max="200" step="5" onmousemove="apply()" ontouchmove="apply()" style="vertical-align:-7px;"/>
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>
让我们从你的问题来看这部分,因为如果你只支持它工作的浏览器,这就是你所需要的:
Again, I'm lost on the application of the non-CSS filters: How to save image from canvas with css filters
上下文的 filter
property 就像 CSS 过滤器一样工作 – 它具有相同的功能 – 但重要的是要知道,与 CSS 不同的是,将过滤器应用于context 不会 更改 canvas' current 图像。它仅适用于后续 绘图操作。
这是一个例子。当您 运行 下面的代码片段时,您会看到两个 canvas。第一个应用了 CSS filter
,第二个没有(第一个 canvas 的边框模糊且呈粉红色,而第二个清晰且清晰绿色)。
然后单击 "Copy image" 按钮时,代码
- 查看当前应用于第一个 canvas、 的 CSS 过滤器
- 将此过滤器值应用于第二个上下文,
- 将第一个 canvas 绘制到第二个上。
因为2),3)中的绘图操作会应用滤镜。
第二个 canvas 现在看起来像第一个,但是第二个 canvas 现在真正包含了色调旋转和模糊的像素,而第一个仍然有红色和清晰的像素 – 你只是因为 CSS 过滤器而看不到。
此时,您可以将第二个 canvas保存为图像,它看起来和预期的一样。
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>