diff --git a/actions/blend.js b/actions/blend.js index 59ff9c5..4dc9ce2 100755 --- a/actions/blend.js +++ b/actions/blend.js @@ -1,7 +1,7 @@ /* - * Pixastic Lib - Blend - v0.1.0 + * Pixastic Lib - Blend - v0.1.1 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ - * MIT License [http://www.opensource.org/licenses/mit-license.php] + * License: [http://www.pixastic.com/lib/license.txt] */ Pixastic.Actions.blend = { @@ -13,310 +13,474 @@ Pixastic.Actions.blend = { amount = Math.max(0,Math.min(1,amount)); - var amount1 = 1 - amount; - var amount2 = amount; - if (!image) return false; if (Pixastic.Client.hasCanvasImageData()) { - var data = Pixastic.prepareData(params); var rect = params.options.rect; + var data = Pixastic.prepareData(params); var w = rect.width; var h = rect.height; + params.useData = false; + var otherCanvas = document.createElement("canvas"); - otherCanvas.width = w; - otherCanvas.height = h; + otherCanvas.width = params.canvas.width; + otherCanvas.height = params.canvas.height; var otherCtx = otherCanvas.getContext("2d"); otherCtx.drawImage(image,0,0); - var data2 = otherCtx.getImageData(0,0,w,h).data; - - var w4 = w*4; - var y = h; + var params2 = {canvas:otherCanvas,options:params.options}; + var data2 = Pixastic.prepareData(params2); + var dataDesc2 = params2.canvasData; var p = w*h; + var pix = p*4; + var pix1, pix2; + var r1, g1, b1; + var r2, g2, b2; + var r3, g3, b3; + var r4, g4, b4; + + var dataChanged = false; + switch (mode) { case "normal" : - while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - data[offset] = r1 * amount1 + amount2 * r2; - data[offset+1] = g1 * amount1 + amount2 * g2; - data[offset+2] = b1 * amount1 + amount2 * b2; - } + //while (p--) { + // data2[pix-=4] = data2[pix]; + // data2[pix1=pix+1] = data2[pix1]; + // data2[pix2=pix+2] = data2[pix2]; + //} break; case "multiply" : while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - data[offset] = r1 * amount1 + amount2 * (r1 * r2 / 255); - data[offset+1] = g1 * amount1 + amount2 * (g1 * g2 / 255); - data[offset+2] = b1 * amount1 + amount2 * (b1 * b2 / 255); + data2[pix-=4] = data[pix] * data2[pix] / 255; + data2[pix1=pix+1] = data[pix1] * data2[pix1] / 255; + data2[pix2=pix+2] = data[pix2] * data2[pix2] / 255; } + dataChanged = true; break; case "lighten" : while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - data[offset] = r1 * amount1 + amount2 * (r1 > r2 ? r1 : r2); - data[offset+1] = g1 * amount1 + amount2 * (g1 > g2 ? g1 : g2); - data[offset+2] = b1 * amount1 + amount2 * (b1 > b2 ? b1 : b2); + if ((r1 = data[pix-=4]) > data2[pix]) + data2[pix] = r1; + if ((g1 = data[pix1=pix+1]) > data2[pix1]) + data2[pix1] = g1; + if ((b1 = data[pix2=pix+2]) > data2[pix2]) + data2[pix2] = b1; } + dataChanged = true; break; case "darken" : while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - data[offset] = r1 * amount1 + amount2 * (r1 < r2 ? r1 : r2); - data[offset+1] = g1 * amount1 + amount2 * (g1 < g2 ? g1 : g2); - data[offset+2] = b1 * amount1 + amount2 * (b1 < b2 ? b1 : b2); + if ((r1 = data[pix-=4]) < data2[pix]) + data2[pix] = r1; + if ((g1 = data[pix1=pix+1]) < data2[pix1]) + data2[pix1] = g1; + if ((b1 = data[pix2=pix+2]) < data2[pix2]) + data2[pix2] = b1; + } + dataChanged = true; break; - case "average" : + case "darkercolor" : while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - data[offset] = r1 * amount1 + amount2 * ((r1 + r2) / 2); - data[offset+1] = g1 * amount1 + amount2 * ((g1 + g2) / 2); - data[offset+2] = b1 * amount1 + amount2 * ((b1 + b2) / 2); + if (((r1 = data[pix-=4])*0.3+(g1 = data[pix1=pix+1])*0.59+(b1 = data[pix2=pix+2])*0.11) <= (data2[pix]*0.3+data2[pix1]*0.59+data2[pix2]*0.11)) { + data2[pix] = r1; + data2[pix1] = g1; + data2[pix2] = b1; + } } + dataChanged = true; + break; + + case "lightercolor" : + while (p--) { + if (((r1 = data[pix-=4])*0.3+(g1 = data[pix1=pix+1])*0.59+(b1 = data[pix2=pix+2])*0.11) > (data2[pix]*0.3+data2[pix1]*0.59+data2[pix2]*0.11)) { + data2[pix] = r1; + data2[pix1] = g1; + data2[pix2] = b1; + } + } + dataChanged = true; break; case "lineardodge" : + otherCtx.globalCompositeOperation = "source-over"; + otherCtx.drawImage(params.canvas, 0, 0); + otherCtx.globalCompositeOperation = "lighter"; + otherCtx.drawImage(image, 0, 0); + + /* while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - var r3 = r1+r2, g3 = g1+g2, b3 = b1+b2; - data[offset] = r1 * amount1 + amount2 * (r3 > 255 ? 255 : r3); - data[offset+1] = g1 * amount1 + amount2 * (g3 > 255 ? 255 : g3); - data[offset+2] = b1 * amount1 + amount2 * (b3 > 255 ? 255 : b3); + if ((r3 = data[pix-=4] + data2[pix]) > 255) + data2[pix] = 255; + else + data2[pix] = r3; + if ((g3 = data[pix1=pix+1] + data2[pix1]) > 255) + data2[pix1] = 255; + else + data2[pix1] = g3; + if ((b3 = data[pix2=pix+2] + data2[pix2]) > 255) + data2[pix2] = 255; + else + data2[pix2] = b3; } + dataChanged = true; + */ + break; case "linearburn" : while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - var r3 = (r2+r1 < 255) ? 0 : (r2+r1-255); - var g3 = (g2+g1 < 255) ? 0 : (g2+g1-255); - var b3 = (b2+b1 < 255) ? 0 : (b2+b1-255); - - data[offset] = r1 * amount1 + amount2 * (r3 < 0 ? 0 : r3); - data[offset+1] = g1 * amount1 + amount2 * (g3 < 0 ? 0 : g3); - data[offset+2] = b1 * amount1 + amount2 * (b3 < 0 ? 0 : b3); + if ((r3 = data[pix-=4] + data2[pix]) < 255) + data2[pix] = 0; + else + data2[pix] = (r3 - 255); + if ((g3 = data[pix1=pix+1] + data2[pix1]) < 255) + data2[pix1] = 0; + else + data2[pix1] = (g3 - 255); + if ((b3 = data[pix2=pix+2] + data2[pix2]) < 255) + data2[pix2] = 0; + else + data2[pix2] = (b3 - 255); } + dataChanged = true; break; case "difference" : while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - var r3 = r1-r2, g3 = g1-g2, b3 = b1-b2; - data[offset] = r1 * amount1 + amount2 * (r3 < 0 ? -r3 : r3); - data[offset+1] = g1 * amount1 + amount2 * (g3 < 0 ? -g3 : g3); - data[offset+2] = b1 * amount1 + amount2 * (b3 < 0 ? -b3 : b3); + if ((r3 = data[pix-=4] - data2[pix]) < 0) + data2[pix] = -r3; + else + data2[pix] = r3; + if ((g3 = data[pix1=pix+1] - data2[pix1]) < 0) + data2[pix1] = -g3; + else + data2[pix1] = g3; + if ((b3 = data[pix2=pix+2] - data2[pix2]) < 0) + data2[pix2] = -b3; + else + data2[pix2] = b3; } + dataChanged = true; break; - case "screen" : while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - var r3 = (255 - (((255 - r2) * (255 - r1)) >> 8)); - var g3 = (255 - (((255 - g2) * (255 - g1)) >> 8)); - var b3 = (255 - (((255 - b2) * (255 - b1)) >> 8)); - data[offset] = r1 * amount1 + amount2 * r3; - data[offset+1] = g1 * amount1 + amount2 * g3; - data[offset+2] = b1 * amount1 + amount2 * b3; + data2[pix-=4] = (255 - ( ((255-data2[pix])*(255-data[pix])) >> 8)); + data2[pix1=pix+1] = (255 - ( ((255-data2[pix1])*(255-data[pix1])) >> 8)); + data2[pix2=pix+2] = (255 - ( ((255-data2[pix2])*(255-data[pix2])) >> 8)); } + dataChanged = true; break; case "exclusion" : + var div_2_255 = 2 / 255; while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - var r3 = r2 + r1 - 2 * r2 * r1 / 255; - var g3 = g2 + g1 - 2 * g2 * g1 / 255; - var b3 = b2 + b1 - 2 * b2 * b1 / 255; - data[offset] = r1 * amount1 + amount2 * r3; - data[offset+1] = g1 * amount1 + amount2 * g3; - data[offset+2] = b1 * amount1 + amount2 * b3; + data2[pix-=4] = (r1 = data[pix]) - (r1 * div_2_255 - 1) * data2[pix]; + data2[pix1=pix+1] = (g1 = data[pix1]) - (g1 * div_2_255 - 1) * data2[pix1]; + data2[pix2=pix+2] = (b1 = data[pix2]) - (b1 * div_2_255 - 1) * data2[pix2]; } + dataChanged = true; break; case "overlay" : + var div_2_255 = 2 / 255; while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - var r3 = ((r1 < 128) ? (2*r2*r1/255) : (255-2*(255-r2) * (255-r1)/255)); - var g3 = ((g1 < 128) ? (2*g2*g1/255) : (255-2*(255-g2) * (255-g1)/255)); - var b3 = ((b1 < 128) ? (2*b2*b1/255) : (255-2*(255-b2) * (255-b1)/255)); - data[offset] = r1 * amount1 + amount2 * r3; - data[offset+1] = g1 * amount1 + amount2 * g3; - data[offset+2] = b1 * amount1 + amount2 * b3; + if ((r1 = data[pix-=4]) < 128) + data2[pix] = data2[pix]*r1*div_2_255; + else + data2[pix] = 255 - (255-data2[pix])*(255-r1)*div_2_255; + + if ((g1 = data[pix1=pix+1]) < 128) + data2[pix1] = data2[pix1]*g1*div_2_255; + else + data2[pix1] = 255 - (255-data2[pix1])*(255-g1)*div_2_255; + + if ((b1 = data[pix2=pix+2]) < 128) + data2[pix2] = data2[pix2]*b1*div_2_255; + else + data2[pix2] = 255 - (255-data2[pix2])*(255-b1)*div_2_255; + } + dataChanged = true; break; case "softlight" : + var div_2_255 = 2 / 255; while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - var r3 = ((r1 < 128) ? (2*((r2>>1)+64))*(r1/255) : (255-(2*(255-((r2>>1)+64))*(255-r1)/255))); - var g3 = ((g1 < 128) ? (2*((g2>>1)+64))*(g1/255) : (255-(2*(255-((g2>>1)+64))*(255-g1)/255))); - var b3 = ((b1 < 128) ? (2*((b2>>1)+64))*(b1/255) : (255-(2*(255-((b2>>1)+64))*(255-b1)/255))); - data[offset] = r1 * amount1 + amount2 * r3; - data[offset+1] = g1 * amount1 + amount2 * g3; - data[offset+2] = b1 * amount1 + amount2 * b3; + if ((r1 = data[pix-=4]) < 128) + data2[pix] = ((data2[pix]>>1) + 64) * r1 * div_2_255; + else + data2[pix] = 255 - (191 - (data2[pix]>>1)) * (255-r1) * div_2_255; + + if ((g1 = data[pix1=pix+1]) < 128) + data2[pix1] = ((data2[pix1]>>1)+64) * g1 * div_2_255; + else + data2[pix1] = 255 - (191 - (data2[pix1]>>1)) * (255-g1) * div_2_255; + + if ((b1 = data[pix2=pix+2]) < 128) + data2[pix2] = ((data2[pix2]>>1)+64) * b1 * div_2_255; + else + data2[pix2] = 255 - (191 - (data2[pix2]>>1)) * (255-b1) * div_2_255; + } + dataChanged = true; break; - case "hardlight" : + var div_2_255 = 2 / 255; while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - var r3 = ((r2 < 128) ? (2*r1*r2/255) : (255-2*(255-r1) * (255-r2)/255)); - var g3 = ((g2 < 128) ? (2*g1*g2/255) : (255-2*(255-g1) * (255-g2)/255)); - var b3 = ((b2 < 128) ? (2*b1*b2/255) : (255-2*(255-b1) * (255-b2)/255)); - data[offset] = r1 * amount1 + amount2 * r3; - data[offset+1] = g1 * amount1 + amount2 * g3; - data[offset+2] = b1 * amount1 + amount2 * b3; + if ((r2 = data2[pix-=4]) < 128) + data2[pix] = data[pix] * r2 * div_2_255; + else + data2[pix] = 255 - (255-data[pix]) * (255-r2) * div_2_255; + + if ((g2 = data2[pix1=pix+1]) < 128) + data2[pix1] = data[pix1] * g2 * div_2_255; + else + data2[pix1] = 255 - (255-data[pix1]) * (255-g2) * div_2_255; + + if ((b2 = data2[pix2=pix+2]) < 128) + data2[pix2] = data[pix2] * b2 * div_2_255; + else + data2[pix2] = 255 - (255-data[pix2]) * (255-b2) * div_2_255; + } + dataChanged = true; break; case "colordodge" : while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - var r3 = (r2 == 255) ? 255 : ((r1<<8)/(255-r2)); - var g3 = (g2 == 255) ? 255 : ((g1<<8)/(255-g2)); - var b3 = (b2 == 255) ? 255 : ((b1<<8)/(255-b2)); - data[offset] = r1 * amount1 + amount2 * (r3 > 255 ? 255 : r3); - data[offset+1] = g1 * amount1 + amount2 * (g3 > 255 ? 255 : g3); - data[offset+2] = b1 * amount1 + amount2 * (b3 > 255 ? 255 : b3); + if ((r3 = (data[pix-=4]<<8)/(255-(r2 = data2[pix]))) > 255 || r2 == 255) + data2[pix] = 255; + else + data2[pix] = r3; + + if ((g3 = (data[pix1=pix+1]<<8)/(255-(g2 = data2[pix1]))) > 255 || g2 == 255) + data2[pix1] = 255; + else + data2[pix1] = g3; + + if ((b3 = (data[pix2=pix+2]<<8)/(255-(b2 = data2[pix2]))) > 255 || b2 == 255) + data2[pix2] = 255; + else + data2[pix2] = b3; } + dataChanged = true; break; case "colorburn" : while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - var r3 = (r2 == 0) ? 0 : (255-((255-r1)<<8)/r2); - var g3 = (g2 == 0) ? 0 : (255-((255-g1)<<8)/g2); - var b3 = (b2 == 0) ? 0 : (255-((255-b1)<<8)/b2); - data[offset] = r1 * amount1 + amount2 * (r3 < 0 ? 0 : r3); - data[offset+1] = g1 * amount1 + amount2 * (g3 < 0 ? 0 : g3); - data[offset+2] = b1 * amount1 + amount2 * (b3 < 0 ? 0 : b3); + if ((r3 = 255-((255-data[pix-=4])<<8)/data2[pix]) < 0 || data2[pix] == 0) + data2[pix] = 0; + else + data2[pix] = r3; + + if ((g3 = 255-((255-data[pix1=pix+1])<<8)/data2[pix1]) < 0 || data2[pix1] == 0) + data2[pix1] = 0; + else + data2[pix1] = g3; + + if ((b3 = 255-((255-data[pix2=pix+2])<<8)/data2[pix2]) < 0 || data2[pix2] == 0) + data2[pix2] = 0; + else + data2[pix2] = b3; } + dataChanged = true; break; case "linearlight" : while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - var r3 = (r2 < 128) ? ((2*r2+r1 < 255) ? 0 : (2*r2+r1-255)) : (r1+(2*(r2-128))); - var g3 = (g2 < 128) ? ((2*g2+g1 < 255) ? 0 : (2*g2+g1-255)) : (g1+(2*(g2-128))); - var b3 = (b2 < 128) ? ((2*b2+r1 < 255) ? 0 : (2*b2+r1-255)) : (b1+(2*(b2-128))); - if (r3 > 255) r3 = 255; - if (g3 > 255) g3 = 255; - if (b3 > 255) b3 = 255; - data[offset] = r1 * amount1 + amount2 * (r3 < 0 ? 0 : r3); - data[offset+1] = g1 * amount1 + amount2 * (g3 < 0 ? 0 : g3); - data[offset+2] = b1 * amount1 + amount2 * (b3 < 0 ? 0 : b3); + if ( ((r3 = 2*(r2=data2[pix-=4])+data[pix]-256) < 0) || (r2 < 128 && r3 < 0)) { + data2[pix] = 0 + } else { + if (r3 > 255) + data2[pix] = 255; + else + data2[pix] = r3; + } + if ( ((g3 = 2*(g2=data2[pix1=pix+1])+data[pix1]-256) < 0) || (g2 < 128 && g3 < 0)) { + data2[pix1] = 0 + } else { + if (g3 > 255) + data2[pix1] = 255; + else + data2[pix1] = g3; + } + if ( ((b3 = 2*(b2=data2[pix2=pix+2])+data[pix2]-256) < 0) || (b2 < 128 && b3 < 0)) { + data2[pix2] = 0 + } else { + if (b3 > 255) + data2[pix2] = 255; + else + data2[pix2] = b3; + } } + dataChanged = true; break; case "vividlight" : while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - var r3 = (r2 < 128) ? ((r2 == 0) ? 0 : (255-((255-r1)<<8)/(2*r2))) : - (((2*(r2-128)) == 255) ? 255 : ((r1<<8)/(255-(2*(r2-128))))); + if ((r2=data2[pix-=4]) < 128) { + if (r2) { + if ((r3 = 255 - ((255-data[pix])<<8) / (2*r2)) < 0) + data2[pix] = 0; + else + data2[pix] = r3 + } else { + data2[pix] = 0; + } + } else if ((r3 = (r4=2*r2-256)) < 255) { + if ((r3 = (data[pix]<<8)/(255-r4)) > 255) + data2[pix] = 255; + else + data2[pix] = r3; + } else { + if (r3 < 0) + data2[pix] = 0; + else + data2[pix] = r3 + } - var g3 = (g2 < 128) ? ((g2 == 0) ? 0 : (255-((255-g1)<<8)/(2*g2))) : - (((2*(g2-128)) == 255) ? 255 : ((g1<<8)/(255-(2*(g2-128))))); + if ((g2=data2[pix1=pix+1]) < 128) { + if (g2) { + if ((g3 = 255 - ((255-data[pix1])<<8) / (2*g2)) < 0) + data2[pix1] = 0; + else + data2[pix1] = g3; + } else { + data2[pix1] = 0; + } + } else if ((g3 = (g4=2*g2-256)) < 255) { + if ((g3 = (data[pix1]<<8)/(255-g4)) > 255) + data2[pix1] = 255; + else + data2[pix1] = g3; + } else { + if (g3 < 0) + data2[pix1] = 0; + else + data2[pix1] = g3; + } - var b3 = (b2 < 128) ? ((b2 == 0) ? 0 : (255-((255-b1)<<8)/(2*b2))) : - (((2*(b2-128)) == 255) ? 255 : ((b1<<8)/(255-(2*(b2-128))))); - - if (r3 > 255) r3 = 255; - if (g3 > 255) g3 = 255; - if (b3 > 255) b3 = 255; - data[offset] = r1 * amount1 + amount2 * (r3 < 0 ? 0 : r3); - data[offset+1] = g1 * amount1 + amount2 * (g3 < 0 ? 0 : g3); - data[offset+2] = b1 * amount1 + amount2 * (b3 < 0 ? 0 : b3); + if ((b2=data2[pix2=pix+2]) < 128) { + if (b2) { + if ((b3 = 255 - ((255-data[pix2])<<8) / (2*b2)) < 0) + data2[pix2] = 0; + else + data2[pix2] = b3; + } else { + data2[pix2] = 0; + } + } else if ((b3 = (b4=2*b2-256)) < 255) { + if ((b3 = (data[pix2]<<8)/(255-b4)) > 255) + data2[pix2] = 255; + else + data2[pix2] = b3; + } else { + if (b3 < 0) + data2[pix2] = 0; + else + data2[pix2] = b3; + } } + dataChanged = true; break; case "pinlight" : while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; + if ((r2=data2[pix-=4]) < 128) + if ((r1=data[pix]) < (r4=2*r2)) + data2[pix] = r1; + else + data2[pix] = r4; + else + if ((r1=data[pix]) > (r4=2*r2-256)) + data2[pix] = r1; + else + data2[pix] = r4; - var r3 = (r2 < 128) ? (r1 < (2*r2) ? r1 : (2*r2)) : (r1 > (2*(r2-128)) ? r1 : (2*(r2-128))); - var g3 = (g2 < 128) ? (g1 < (2*g2) ? g1 : (2*g2)) : (g1 > (2*(g2-128)) ? g1 : (2*(g2-128))); - var b3 = (b2 < 128) ? (b1 < (2*b2) ? b1 : (2*b2)) : (b1 > (2*(b2-128)) ? b1 : (2*(b2-128))); + if ((g2=data2[pix1=pix+1]) < 128) + if ((g1=data[pix1]) < (g4=2*g2)) + data2[pix1] = g1; + else + data2[pix1] = g4; + else + if ((g1=data[pix1]) > (g4=2*g2-256)) + data2[pix1] = g1; + else + data2[pix1] = g4; - data[offset] = r1 * amount1 + amount2 * r3; - data[offset+1] = g1 * amount1 + amount2 * g3; - data[offset+2] = b1 * amount1 + amount2 * b3; + if ((r2=data2[pix2=pix+2]) < 128) + if ((r1=data[pix2]) < (r4=2*r2)) + data2[pix2] = r1; + else + data2[pix2] = r4; + else + if ((r1=data[pix2]) > (r4=2*r2-256)) + data2[pix2] = r1; + else + data2[pix2] = r4; } + dataChanged = true; break; case "hardmix" : while (p--) { - var offset = p*4; - var r1 = data[offset], g1 = data[offset+1], b1 = data[offset+2]; - var r2 = data2[offset], g2 = data2[offset+1], b2 = data2[offset+2]; - var r3 = (r2 < 128) ? ((r2 == 0) ? 0 : (255-((255-r1)<<8)/(2*r2))) : - (((2*(r2-128)) == 255) ? 255 : ((r1<<8)/(255-(2*(r2-128))))); + if ((r2 = data2[pix-=4]) < 128) + if (255 - ((255-data[pix])<<8)/(2*r2) < 128 || r2 == 0) + data2[pix] = 0; + else + data2[pix] = 255; + else if ((r4=2*r2-256) < 255 && (data[pix]<<8)/(255-r4) < 128) + data2[pix] = 0; + else + data2[pix] = 255; - var g3 = (g2 < 128) ? ((g2 == 0) ? 0 : (255-((255-g1)<<8)/(2*g2))) : - (((2*(g2-128)) == 255) ? 255 : ((g1<<8)/(255-(2*(g2-128))))); + if ((g2 = data2[pix1=pix+1]) < 128) + if (255 - ((255-data[pix1])<<8)/(2*g2) < 128 || g2 == 0) + data2[pix1] = 0; + else + data2[pix1] = 255; + else if ((g4=2*g2-256) < 255 && (data[pix1]<<8)/(255-g4) < 128) + data2[pix1] = 0; + else + data2[pix1] = 255; - var b3 = (b2 < 128) ? ((b2 == 0) ? 0 : (255-((255-b1)<<8)/(2*b2))) : - (((2*(b2-128)) == 255) ? 255 : ((b1<<8)/(255-(2*(b2-128))))); - - data[offset] = r1 * amount1 + amount2 * (r3 < 128 ? 0 : 255); - data[offset+1] = g1 * amount1 + amount2 * (g3 < 128 ? 0 : 255); - data[offset+2] = b1 * amount1 + amount2 * (b3 < 128 ? 0 : 255); + if ((b2 = data2[pix2=pix+2]) < 128) + if (255 - ((255-data[pix2])<<8)/(2*b2) < 128 || b2 == 0) + data2[pix2] = 0; + else + data2[pix2] = 255; + else if ((b4=2*b2-256) < 255 && (data[pix2]<<8)/(255-b4) < 128) + data2[pix2] = 0; + else + data2[pix2] = 255; } + dataChanged = true; break; - -/* -#define ChannelBlend_HardMix(B,L) ((uint8)((ChannelBlend_VividLight(B,L) < 128) ? 0:255)) -#define ChannelBlend_Reflect(B,L) ((uint8)((L == 255) ? L:min(255, (B * B / (255 - L))))) -#define ChannelBlend_Glow(B,L) (ChannelBlend_Reflect(L,B)) -#define ChannelBlend_Phoenix(B,L) ((uint8)(min(B,L) - max(B,L) + 255)) -#define ChannelBlend_Alpha(B,L,O) ((uint8)(O * B + (1 - O) * L)) -#define ChannelBlend_AlphaF(B,L,F,O) (ChannelBlend_Alpha(F(B,L),B,O)) -*/ } + if (dataChanged) + otherCtx.putImageData(dataDesc2,0,0); + + var ctx = params.canvas.getContext("2d"); + ctx.save(); + ctx.globalAlpha = amount; + ctx.drawImage( + otherCanvas, + 0,0,rect.width,rect.height, + rect.left,rect.top,rect.width,rect.height + ); + ctx.globalAlpha = 1; + ctx.restore(); + return true; } }, diff --git a/actions/brightness.js b/actions/brightness.js index 930a8bb..456b1c4 100755 --- a/actions/brightness.js +++ b/actions/brightness.js @@ -1,7 +1,7 @@ /* - * Pixastic Lib - Brightness/Contrast filter - v0.1.0 + * Pixastic Lib - Brightness/Contrast filter - v0.1.1 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ - * MIT License [http://www.opensource.org/licenses/mit-license.php] + * License: [http://www.pixastic.com/lib/license.txt] */ Pixastic.Actions.brightness = { @@ -24,43 +24,51 @@ Pixastic.Actions.brightness = { var rect = params.options.rect; var w = rect.width; var h = rect.height; - var w4 = w*4; - var y = h; - do { - var offsetY = (y-1)*w4; - var x = w; - do { - var offset = offsetY + (x-1)*4; - if (legacy) { - var r = data[offset] + brightness; - var g = data[offset+1] + brightness; - var b = data[offset+2] + brightness; - } else { - var r = data[offset] * brightMul; - var g = data[offset+1] * brightMul; - var b = data[offset+2] * brightMul; - } + var p = w*h; + var pix = p*4, pix1, pix2; - if (contrast != 1) { - r = (r - 128) * contrast + 128; - g = (g - 128) * contrast + 128; - b = (b - 128) * contrast + 128; - } + var mul, add; + if (contrast != 1) { + if (legacy) { + mul = contrast; + add = (brightness - 128) * contrast + 128; + } else { + mul = brightMul * contrast; + add = - contrast * 128 + 128; + } + } else { // this if-then is not necessary anymore, is it? + if (legacy) { + mul = 1; + add = brightness; + } else { + mul = brightMul; + add = 0; + } + } + var r, g, b; + while (p--) { + if ((r = data[pix-=4] * mul + add) > 255 ) + data[pix] = 255; + else if (r < 0) + data[pix] = 0; + else + data[pix] = r; - if (r < 0 ) r = 0; - if (g < 0 ) g = 0; - if (b < 0 ) b = 0; - if (r > 255 ) r = 255; - if (g > 255 ) g = 255; - if (b > 255 ) b = 255; + if ((g = data[pix1=pix+1] * mul + add) > 255 ) + data[pix1] = 255; + else if (g < 0) + data[pix1] = 0; + else + data[pix1] = g; - data[offset] = r; - data[offset+1] = g; - data[offset+2] = b; - - } while (--x); - } while (--y); + if ((b = data[pix2=pix+2] * mul + add) > 255 ) + data[pix2] = 255; + else if (b < 0) + data[pix2] = 0; + else + data[pix2] = b; + } return true; } }, diff --git a/actions/desaturate.js b/actions/desaturate.js index a122137..e8d1cdd 100755 --- a/actions/desaturate.js +++ b/actions/desaturate.js @@ -1,7 +1,7 @@ /* - * Pixastic Lib - Desaturation filter - v0.1.0 + * Pixastic Lib - Desaturation filter - v0.1.1 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ - * MIT License [http://www.opensource.org/licenses/mit-license.php] + * License: [http://www.pixastic.com/lib/license.txt] */ Pixastic.Actions.desaturate = { @@ -14,19 +14,17 @@ Pixastic.Actions.desaturate = { var rect = params.options.rect; var w = rect.width; var h = rect.height; - var w4 = w*4; - var y = h; - do { - var offsetY = (y-1)*w4; - var x = w; - do { - var offset = offsetY + (x-1)*4; - var brightness = useAverage ? - (data[offset]+data[offset+1]+data[offset+2])/3 - : (data[offset]*0.3 + data[offset+1]*0.59 + data[offset+2]*0.11); - data[offset] = data[offset+1] = data[offset+2] = brightness; - } while (--x); - } while (--y); + + var p = w*h; + var pix = p*4, pix1, pix2; + + if (useAverage) { + while (p--) + data[pix-=4] = data[pix1=pix+1] = data[pix2=pix+2] = (data[pix]+data[pix1]+data[pix2])/3 + } else { + while (p--) + data[pix-=4] = data[pix1=pix+1] = data[pix2=pix+2] = (data[pix]*0.3 + data[pix1]*0.59 + data[pix2]*0.11); + } return true; } else if (Pixastic.Client.isIE()) { params.image.style.filter += " gray";