Javascript 为什么可以';我不能还原画布上的亮度吗?
我使用画布设置图像的亮度。如果我只设置一次亮度,这项工作就可以了。但是如果我将亮度重置为0,则不会得到默认图像。我不知道为什么 调用效果的代码:Javascript 为什么可以';我不能还原画布上的亮度吗?,javascript,canvas,Javascript,Canvas,我使用画布设置图像的亮度。如果我只设置一次亮度,这项工作就可以了。但是如果我将亮度重置为0,则不会得到默认图像。我不知道为什么 调用效果的代码: var mainEffect = new CanvasEffect(canvas[0]); var thumbsEffect = new CanvasEffect(thumbs[0]); luminositySlider.change(function() { var intensity = luminositySlider.val();
var mainEffect = new CanvasEffect(canvas[0]);
var thumbsEffect = new CanvasEffect(thumbs[0]);
luminositySlider.change(function() {
var intensity = luminositySlider.val();
mainEffect.apply("luminosity", intensity);
thumbsEffect.apply("luminosity", intensity);
});
这是我使用的代码,int是从html滑块获得的。以前的亮度存储在一个数组中:
function CanvasEffect(canvas) {
var ctx = canvas.getContext("2d");
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var stack = [];
var imageData;
var data;
this.apply = function(effect, intensity) {
imageData = ctx.getImageData(0,0, WIDTH, HEIGHT);
data = imageData.data;
var int = Number(intensity);
var refresh = true;
switch (effect) {
case "blur":
refresh = false;
stackBlurCanvasRGB('canvas', 0, 0, WIDTH, HEIGHT, int);
break;
case "sharpen":
break;
case "luminosity":
console.log("stack['luminosity'] : " + stack["luminosity"]);
lastInt = (stack["luminosity"] == undefined) ? 0 : stack["luminosity"];
newInt = int - lastInt;
console.log("int : " + int, "lastInt : " + lastInt, "newInt : " + newInt);
for(var i=0;i < data.length;i+=4) {
data[i] += newInt; //Red
data[i+1] += newInt; //Green
data[i+2] += newInt; //Blue
}
break;
case "contrast":
lastInt = (stack["contrast"] == undefined) ? 0 : stack["contrast"];
newInt = int - lastInt;
var factor = (259 * (newInt + 255)) / (255 * (259 - newInt));
for(var i = 0; i < data.length ; i+=4) {
data[i] = factor * (data[i] - 128) + 128; //Red
data[i+1] = factor * (data[i+1] - 128) + 128; //Green
data[i+2] = factor * (data[i+2] - 128) + 128; //Blue
}
break;
case "negatif":
console.log("negatif");
for(var i=0;i < data.length;i+=4) {
data[i] = 256-data[i]; //Red
data[i+1] = 256-data[i+1]; //Green
data[i+2] = 256 - data[i+2]; //Blue
}
break;
case "b&w":
console.log("b&w");
for(var i=0;i < data.length;i+=4) {
var gris = data[i]*0.3 + data[i+1]*0.59 + data[i+2]*0.11;
data[i] = gris; //Red
data[i+1] = gris; //Green
data[i+2] = gris; //Blue
}
break;
case "sepia":
console.log("sepia");
for(var i=0;i < data.length;i+=4) {
var r = data[i]*0.299 + data[i+1]*0.587 + data[i+2]*0.114;
data[i] = Math.max(0, Math.min(255, r*1.351)); //Red
data[i+1] = Math.max(0, Math.min(255, r*1.203)); //Green
data[i+2] = Math.max(0, Math.min(255, r*0.937)); //Blue
}
break;
default:
break;
}
if(refresh) {
imageData.data = data;
ctx.putImageData(imageData,0 ,0);
}
// Stores the effect to recalculate if it changes
stack[effect] = int;
};
函数画布效果(画布){
var ctx=canvas.getContext(“2d”);
var WIDTH=canvas.WIDTH;
var HEIGHT=canvas.HEIGHT;
var堆栈=[];
var图像数据;
var数据;
this.apply=功能(效果、强度){
imageData=ctx.getImageData(0,0,宽度,高度);
data=imageData.data;
var int=数量(强度);
var刷新=真;
开关(效果){
案例“模糊”:
刷新=错误;
stackBlurCanvasRGB(“画布”,0,0,宽度,高度,整数);
打破
案例“锐化”:
打破
案例“亮度”:
log(“stack['luminity']:”+stack['luminity']);
lastInt=(堆栈[“亮度”]==未定义)?0:堆栈[“亮度”];
newInt=int-lastInt;
log(“int:+int,lastin:+lastin,newInt:+newInt”);
对于(变量i=0;i
}
原始图像:
具有最大亮度的图像:
将图像重置为原始图像(亮度0):
您烧掉了图像。您需要从文件中重新加载图像,以恢复过度曝光的像素的信息
画布加载图像后,会“忘记”原始文件,只处理加载的像素。当你增加亮度时,那张图片的一个大区域丢失了信息,因为它“超出了比例”。除非重新加载图片,否则无法恢复丢失的信息
更新:正如@gamealchest所建议的,您可以创建自己的阵列:
var image= new Int32Array(originalByteArray); //Or Float32Array, I'd test both
并在那里存储图像的副本。然后,对该数组执行所有操作,并在图像数据中复制输出,仅取前8位。如您所知,r、g、b、a分量存储在8位上,这8位太少,无法进行多次操作:在每次操作中,将发生舍入和钳位
解决方案是使用Float32Array存储图像的组件。然后,您可以执行任何种类和数量的操作,并且(几乎)不会损失质量 好吧,这将是一场表演的噩梦。如果我有多个过滤器。我必须重置图像并再次应用所有过滤器?使用int32扩展动态范围是可能的,但需要仔细编程以避免出现溢出/下溢/舍入问题。不值得我这么努力。