我正在创建一个网页,允许用户在上传的图像中添加滤色器。为了做到这一点,我希望将图像的原始副本存储在画布中。然后,每当用户更改其中一个颜色值时,我想使用范围滑块将原始图像复制到新的画布中,对其进行编辑,然后绘制新图像。
我不想将更改直接应用于原始图像的原因是它们可能很难反转。例如,如果用户将图像的蓝色通道设置为0,那么除非我有原始图像,否则用户将无法撤消该效果。
我目前的解决方案是创建一个包含画布元素的闭包。当用户上传照片时,会初始化此关闭。我的关闭代码低于
var scaleCanvas = (function() {
var scaledCvs = document.createElement('canvas'); //Creates a canvas object
var scaledCtx = scaledCvs.getContext("2d"); //Gets canvas context
// All the functions in this section can access scaledCanvas
return {
init: function(cvs) {
scaledCvs = cvs;
console.log("Image Stored")
}, //close init
getImg: function() {
return (scaledCvs);
} //Close getImg
}; //close return
})();
画布初始化后,可以使用scaleCcanvas.getImg((函数对其进行访问。这方面的一个例子是在我的函数adjustFilters((期间,它被下面的范围滑块元素调用
<div class="slidecontainer">
<label>Blue Channel</label>
<input type="range" min="0" max="150" value="100" class="slider" id="blue" onchange="adjustFilters();"/>
</div>
蓝色滑块更改后,我加载要用于显示图像的画布。然后我使用scaleCcanvas.getImg((加载我的原始图像。然后我应用我感兴趣的效果。然后我绘制图像。但奇怪的是,我的闭包中的scaledCV变量似乎正在更改。我这样说是因为如果我为"0"选择一个值;蓝色";如果为0,则我不可能恢复原始的蓝色通道。除非我的闭包中的scaledCV被以某种方式更改,否则这不应该发生。
function adjustFilters() {
var canvas = document.getElementById("dispImg"); //gets the canvas element
canvas.style.display = "block"; //Makes the canvas visible
var context = canvas.getContext("2d"); //Using 2D context
// look up the size the canvas is being displayed at
const width = canvas.clientWidth;
const height = canvas.clientHeight;
var imgCV = scaleCanvas.getImg(); //Gets the original canvas image
var imgCtx = imgCV.getContext('2d');
var blue = document.getElementById("blue").value / 100; //Gets value of the blue slider
// Adjusts blue channel
adjustColor(imgCtx, imgCV.height, imgCV.width, "blue", blue)
// Draws the Image
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(imgCV, 0, 0);
}
我正在寻找如何使我的代码按预期运行的建议。即,除了调用init函数外,我需要不调整闭包中的变量scaledCvs。
谢谢
观察到的行为的原因是画布元素是通过引用传递的,因此
init: function(cvs) {
scaledCvs = cvs;
console.log("Image Stored")
}, //close init
不创建cvs的副本,它只是创建一个对它的引用。为了创建实际画布的副本,你需要遵循下面的协议
init: function(cvs) {
//Create a Copy of the provided canvas (cvs)
scaledCvs.width=cvs.width;
scaledCvs.height=cvs.height;
scaledCtx.drawImage(cvs,0,0);
}, //close init
为了使整个代码正常工作,您还需要修改getImage((,这样它就不会被传递scaledCV的引用。最终的关闭定义将是
var scaleCanvas = (function() {
var scaledCvs=document.createElement('canvas'); //Creates a canvas object
var scaledCtx=scaledCvs.getContext("2d"); //Gets canvas context
// All the functions in this section can access scaledCanvas
return {
init: function(cvs) {
//Create a Copy of the provided canvas (cvs)
scaledCvs.width=cvs.width;
scaledCvs.height=cvs.height;
scaledCtx.drawImage(cvs,0,0);
}, //close init
getImg: function() {
//Since canvas are passed by reference in order to protect the saved canvas I have to create a copy before passing it out
var cpCanvas = document.createElement('canvas');
var context = cpCanvas.getContext("2d");
cpCanvas.height = scaledCvs.height;
cpCanvas.width = scaledCvs.width;
context.drawImage(scaledCvs,0,0);
return(cpCanvas);
} //Close getImg
}; //close return
})();
所有其他代码可以保持不变。