Changer la luminosité d'une image avec canvas
Bonjour.
J'essaye de faire une classe javascript me permettant de manipuler une image avec un canvas. Jusqu’à présent j'ai réussi à faire les changements souhaités( contraste, luminosité, noir&blanc, etc ...). Seulement les modifications de contraste et de luminosité ne fonctionne qu'une fois. Je m'explique. Ces modifications sont appliqués à l'aide d'un curseur allant de -100 à 100. Si je déplace le curseur à la valeur 100. Tout ce passe très bien. Mon image deviens très lumineuse. Seulement si je le ramène à 0, je ne retrouve pas l'image de départ. Après quelque recherche, cela viens du format RGB qui ne peut stocker que 255 valeur pour chaque couleur. Ainsi en haute luminosité. l'image est "brulée et perd des informations. Pour contrer ce phénomène je passe mon image d'un Uint8 clampe à un Int32Array permettant de contenir plus de valeur. Je fais mes changement et je rechange mon Int32Arrayen Uint8 clampe
pour mettre à jour le canvas. Seulement voila. Rien ne se passe au moment du cast. Voici mon code :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
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) {
if(data == undefined) {
imageData = ctx.getImageData(0,0, WIDTH, HEIGHT);
var imgData = imageData.data;
// Save the data of the orignal file.
data= new Int32Array(imgData);
}
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) {
// Voici le code qui ne fonctionne pas
var clampedArray = new Uint8ClampedArray(data); // Conversion vers un Uint8ClampedArray.
var newImgData=ctx.createImageData( WIDTH, HEIGHT);
newImgData.data = clampedArray;
console.log(newImgData.data, clampedArray);
ctx.putImageData(newImgData,0 ,0);
console.log(imgData.data);
}
stack[effect] = int;
};
} |
Si quelqu'un à une idée. Je suis preneur. Je sèche la dessus depuis quelque temps déjà