2 * Pixastic Lib - Core Functions - v0.1.3
3 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
4 * License: [http://www.pixastic.com/lib/license.txt]
7 var Pixastic = (function() {
10 function addEvent(el, event, handler) {
11 if (el.addEventListener)
12 el.addEventListener(event, handler, false);
13 else if (el.attachEvent)
14 el.attachEvent("on" + event, handler);
17 function onready(handler) {
18 var handlerDone = false;
19 var execHandler = function() {
25 document.write("<"+"script defer src=\"//:\" id=\"__onload_ie_sumbox__\"></"+"script>");
26 var script = document.getElementById("__onload_ie_sumbox__");
27 script.onreadystatechange = function() {
28 if (script.readyState == "complete") {
29 script.parentNode.removeChild(script);
33 if (document.addEventListener)
34 document.addEventListener("DOMContentLoaded", execHandler, false);
35 addEvent(window, "load", execHandler);
39 if (!Pixastic.parseOnLoad) return;
40 var imgEls = getElementsByClass("pixastic", null, "img");
41 var canvasEls = getElementsByClass("pixastic", null, "canvas");
42 var elements = imgEls.concat(canvasEls);
43 for (var i=0;i<elements.length;i++) {
48 var classes = el.className.split(" ");
49 for (var c=0;c<classes.length;c++) {
51 if (cls.substring(0,9) == "pixastic-") {
52 var actionName = cls.substring(9);
54 actions.push(actionName);
58 if (el.tagName.toLowerCase() == "img") {
59 var dataImg = new Image();
61 if (dataImg.complete) {
62 for (var a=0;a<actions.length;a++) {
63 var res = Pixastic.applyAction(el, el, actions[a], null);
68 dataImg.onload = function() {
69 for (var a=0;a<actions.length;a++) {
70 var res = Pixastic.applyAction(el, el, actions[a], null)
77 setTimeout(function() {
78 for (var a=0;a<actions.length;a++) {
79 var res = Pixastic.applyAction(
80 el, el, actions[a], null
93 // if (typeof pixastic_no_onready == "undefined") // yuck.
96 // getElementsByClass by Dustin Diaz, http://www.dustindiaz.com/getelementsbyclass/
97 function getElementsByClass(searchClass,node,tag) {
98 var classElements = new Array();
104 var els = node.getElementsByTagName(tag);
105 var elsLen = els.length;
106 var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
107 for (i = 0, j = 0; i < elsLen; i++) {
108 if ( pattern.test(els[i].className) ) {
109 classElements[j] = els[i];
113 return classElements;
118 function writeDebug(text, level) {
119 if (!Pixastic.debug) return;
123 console.warn("Pixastic:", text);
126 console.error("Pixastic:", text);
129 console.log("Pixastic:", text);
145 applyAction : function(img, dataImg, actionName, options) {
147 options = options || {};
149 var imageIsCanvas = (img.tagName.toLowerCase() == "canvas");
150 if (imageIsCanvas && Pixastic.Client.isIE()) {
151 if (Pixastic.debug) writeDebug("Tried to process a canvas element but browser is IE.");
156 if (Pixastic.Client.hasCanvas()) {
157 canvas = document.createElement("canvas");
158 ctx = canvas.getContext("2d");
161 var w = parseInt(img.offsetWidth);
162 var h = parseInt(img.offsetHeight);
169 if (actionName.indexOf("(") > -1) {
170 var tmp = actionName;
171 actionName = tmp.substr(0, tmp.indexOf("("));
172 var arg = tmp.match(/\((.*?)\)/);
174 arg = arg[1].split(";");
175 for (var a=0;a<arg.length;a++) {
176 thisArg = arg[a].split("=");
177 if (thisArg.length == 2) {
178 if (thisArg[0] == "rect") {
179 var rectVal = thisArg[1].split(",");
180 options[thisArg[0]] = {
181 left : parseInt(rectVal[0],10)||0,
182 top : parseInt(rectVal[1],10)||0,
183 width : parseInt(rectVal[2],10)||0,
184 height : parseInt(rectVal[3],10)||0
187 options[thisArg[0]] = thisArg[1];
196 left : 0, top : 0, width : w, height : h
199 var validAction = false;
200 if (Pixastic.Actions[actionName] && typeof Pixastic.Actions[actionName].process == "function") {
204 if (Pixastic.debug) writeDebug("Invalid action \"" + actionName + "\". Maybe file not included?");
207 if (!Pixastic.Actions[actionName].checkSupport()) {
208 if (Pixastic.debug) writeDebug("Action \"" + actionName + "\" not supported by this browser.");
212 if (Pixastic.Client.hasCanvas()) {
215 canvas.style.width = w+"px";
216 canvas.style.height = h+"px";
217 ctx.drawImage(dataImg,0,0,w,h);
219 if (!img.__pixastic_org_image) {
220 canvas.__pixastic_org_image = img;
221 canvas.__pixastic_org_width = w;
222 canvas.__pixastic_org_height = h;
224 canvas.__pixastic_org_image = img.__pixastic_org_image;
225 canvas.__pixastic_org_width = img.__pixastic_org_width;
226 canvas.__pixastic_org_height = img.__pixastic_org_height;
229 } else if (Pixastic.Client.isIE() && typeof img.__pixastic_org_style == "undefined") {
230 img.__pixastic_org_style = img.style.cssText;
244 var res = Pixastic.Actions[actionName].process(params);
250 if (Pixastic.Client.hasCanvas()) {
251 if (params.useData) {
252 if (Pixastic.Client.hasCanvasImageData()) {
253 canvas.getContext("2d").putImageData(params.canvasData, options.rect.left, options.rect.top);
255 // Opera doesn't seem to update the canvas until we draw something on it, lets draw a 0x0 rectangle.
256 canvas.getContext("2d").fillRect(0,0,0,0);
260 if (!options.leaveDOM) {
261 // copy properties and stuff from the source image
262 canvas.title = img.title;
263 canvas.imgsrc = img.imgsrc;
264 if (!imageIsCanvas) canvas.alt = img.alt;
265 if (!imageIsCanvas) canvas.imgsrc = img.src;
266 canvas.className = img.className;
267 canvas.style.cssText = img.style.cssText;
268 canvas.name = img.name;
269 canvas.tabIndex = img.tabIndex;
271 if (img.parentNode && img.parentNode.replaceChild) {
272 img.parentNode.replaceChild(canvas, img);
276 options.resultCanvas = canvas;
284 prepareData : function(params, getCopy) {
285 var ctx = params.canvas.getContext("2d");
286 var rect = params.options.rect;
287 var dataDesc = ctx.getImageData(rect.left, rect.top, rect.width, rect.height);
288 var data = dataDesc.data;
289 if (!getCopy) params.canvasData = dataDesc;
293 // load the image file
294 process : function(img, actionName, options, callback)
296 if (img.tagName.toLowerCase() == "img") {
297 var dataImg = new Image();
298 dataImg.src = img.src;
299 if (dataImg.complete) {
300 var res = Pixastic.applyAction(img, dataImg, actionName, options);
301 if (callback) callback(res);
304 dataImg.onload = function() {
305 var res = Pixastic.applyAction(img, dataImg, actionName, options)
306 if (callback) callback(res);
310 if (img.tagName.toLowerCase() == "canvas") {
311 var res = Pixastic.applyAction(img, img, actionName, options);
312 if (callback) callback(res);
317 revert : function(img) {
318 if (Pixastic.Client.hasCanvas()) {
319 if (img.tagName.toLowerCase() == "canvas" && img.__pixastic_org_image) {
320 img.width = img.__pixastic_org_width;
321 img.height = img.__pixastic_org_height;
322 img.getContext("2d").drawImage(img.__pixastic_org_image, 0, 0);
324 if (img.parentNode && img.parentNode.replaceChild) {
325 img.parentNode.replaceChild(img.__pixastic_org_image, img);
330 } else if (Pixastic.Client.isIE() && typeof img.__pixastic_org_style != "undefined") {
331 img.style.cssText = img.__pixastic_org_style;
336 hasCanvas : (function() {
337 var c = document.createElement("canvas");
340 val = !!((typeof c.getContext == "function") && c.getContext("2d"));
347 hasCanvasImageData : (function() {
348 var c = document.createElement("canvas");
352 if (typeof c.getContext == "function" && (ctx = c.getContext("2d"))) {
353 val = (typeof ctx.getImageData == "function");
362 return !!document.all && !!window.attachEvent && !window.opera;
372 * Pixastic Lib - jQuery plugin
373 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
374 * License: [http://www.pixastic.com/lib/license.txt]
377 if (typeof jQuery != "undefined" && jQuery && jQuery.fn) {
378 jQuery.fn.pixastic = function(action, options) {
379 var newElements = [];
382 if (this.tagName.toLowerCase() == "img" && !this.complete) {
385 var res = Pixastic.process(this, action, options);
387 newElements.push(res);
391 if (newElements.length > 0)
392 return jQuery(newElements);
399 * Pixastic Lib - Blend - v0.1.1
400 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
401 * License: [http://www.pixastic.com/lib/license.txt]
404 Pixastic.Actions.blend = {
406 process : function(params) {
407 var amount = parseFloat(params.options.amount);
408 var mode = (params.options.mode || "normal").toLowerCase();
409 var image = params.options.image;
411 amount = Math.max(0,Math.min(1,amount));
413 if (!image) return false;
415 if (Pixastic.Client.hasCanvasImageData()) {
416 var rect = params.options.rect;
417 var data = Pixastic.prepareData(params);
421 params.useData = false;
423 var otherCanvas = document.createElement("canvas");
424 otherCanvas.width = params.canvas.width;
425 otherCanvas.height = params.canvas.height;
426 var otherCtx = otherCanvas.getContext("2d");
427 otherCtx.drawImage(image,0,0);
429 var params2 = {canvas:otherCanvas,options:params.options};
430 var data2 = Pixastic.prepareData(params2);
431 var dataDesc2 = params2.canvasData;
441 var dataChanged = false;
446 // data2[pix-=4] = data2[pix];
447 // data2[pix1=pix+1] = data2[pix1];
448 // data2[pix2=pix+2] = data2[pix2];
454 data2[pix-=4] = data[pix] * data2[pix] / 255;
455 data2[pix1=pix+1] = data[pix1] * data2[pix1] / 255;
456 data2[pix2=pix+2] = data[pix2] * data2[pix2] / 255;
463 if ((r1 = data[pix-=4]) > data2[pix])
465 if ((g1 = data[pix1=pix+1]) > data2[pix1])
467 if ((b1 = data[pix2=pix+2]) > data2[pix2])
475 if ((r1 = data[pix-=4]) < data2[pix])
477 if ((g1 = data[pix1=pix+1]) < data2[pix1])
479 if ((b1 = data[pix2=pix+2]) < data2[pix2])
488 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)) {
497 case "lightercolor" :
499 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)) {
509 otherCtx.globalCompositeOperation = "source-over";
510 otherCtx.drawImage(params.canvas, 0, 0);
511 otherCtx.globalCompositeOperation = "lighter";
512 otherCtx.drawImage(image, 0, 0);
516 if ((r3 = data[pix-=4] + data2[pix]) > 255)
520 if ((g3 = data[pix1=pix+1] + data2[pix1]) > 255)
524 if ((b3 = data[pix2=pix+2] + data2[pix2]) > 255)
536 if ((r3 = data[pix-=4] + data2[pix]) < 255)
539 data2[pix] = (r3 - 255);
540 if ((g3 = data[pix1=pix+1] + data2[pix1]) < 255)
543 data2[pix1] = (g3 - 255);
544 if ((b3 = data[pix2=pix+2] + data2[pix2]) < 255)
547 data2[pix2] = (b3 - 255);
554 if ((r3 = data[pix-=4] - data2[pix]) < 0)
558 if ((g3 = data[pix1=pix+1] - data2[pix1]) < 0)
562 if ((b3 = data[pix2=pix+2] - data2[pix2]) < 0)
572 data2[pix-=4] = (255 - ( ((255-data2[pix])*(255-data[pix])) >> 8));
573 data2[pix1=pix+1] = (255 - ( ((255-data2[pix1])*(255-data[pix1])) >> 8));
574 data2[pix2=pix+2] = (255 - ( ((255-data2[pix2])*(255-data[pix2])) >> 8));
580 var div_2_255 = 2 / 255;
582 data2[pix-=4] = (r1 = data[pix]) - (r1 * div_2_255 - 1) * data2[pix];
583 data2[pix1=pix+1] = (g1 = data[pix1]) - (g1 * div_2_255 - 1) * data2[pix1];
584 data2[pix2=pix+2] = (b1 = data[pix2]) - (b1 * div_2_255 - 1) * data2[pix2];
590 var div_2_255 = 2 / 255;
592 if ((r1 = data[pix-=4]) < 128)
593 data2[pix] = data2[pix]*r1*div_2_255;
595 data2[pix] = 255 - (255-data2[pix])*(255-r1)*div_2_255;
597 if ((g1 = data[pix1=pix+1]) < 128)
598 data2[pix1] = data2[pix1]*g1*div_2_255;
600 data2[pix1] = 255 - (255-data2[pix1])*(255-g1)*div_2_255;
602 if ((b1 = data[pix2=pix+2]) < 128)
603 data2[pix2] = data2[pix2]*b1*div_2_255;
605 data2[pix2] = 255 - (255-data2[pix2])*(255-b1)*div_2_255;
612 var div_2_255 = 2 / 255;
614 if ((r1 = data[pix-=4]) < 128)
615 data2[pix] = ((data2[pix]>>1) + 64) * r1 * div_2_255;
617 data2[pix] = 255 - (191 - (data2[pix]>>1)) * (255-r1) * div_2_255;
619 if ((g1 = data[pix1=pix+1]) < 128)
620 data2[pix1] = ((data2[pix1]>>1)+64) * g1 * div_2_255;
622 data2[pix1] = 255 - (191 - (data2[pix1]>>1)) * (255-g1) * div_2_255;
624 if ((b1 = data[pix2=pix+2]) < 128)
625 data2[pix2] = ((data2[pix2]>>1)+64) * b1 * div_2_255;
627 data2[pix2] = 255 - (191 - (data2[pix2]>>1)) * (255-b1) * div_2_255;
634 var div_2_255 = 2 / 255;
636 if ((r2 = data2[pix-=4]) < 128)
637 data2[pix] = data[pix] * r2 * div_2_255;
639 data2[pix] = 255 - (255-data[pix]) * (255-r2) * div_2_255;
641 if ((g2 = data2[pix1=pix+1]) < 128)
642 data2[pix1] = data[pix1] * g2 * div_2_255;
644 data2[pix1] = 255 - (255-data[pix1]) * (255-g2) * div_2_255;
646 if ((b2 = data2[pix2=pix+2]) < 128)
647 data2[pix2] = data[pix2] * b2 * div_2_255;
649 data2[pix2] = 255 - (255-data[pix2]) * (255-b2) * div_2_255;
657 if ((r3 = (data[pix-=4]<<8)/(255-(r2 = data2[pix]))) > 255 || r2 == 255)
662 if ((g3 = (data[pix1=pix+1]<<8)/(255-(g2 = data2[pix1]))) > 255 || g2 == 255)
667 if ((b3 = (data[pix2=pix+2]<<8)/(255-(b2 = data2[pix2]))) > 255 || b2 == 255)
677 if ((r3 = 255-((255-data[pix-=4])<<8)/data2[pix]) < 0 || data2[pix] == 0)
682 if ((g3 = 255-((255-data[pix1=pix+1])<<8)/data2[pix1]) < 0 || data2[pix1] == 0)
687 if ((b3 = 255-((255-data[pix2=pix+2])<<8)/data2[pix2]) < 0 || data2[pix2] == 0)
697 if ( ((r3 = 2*(r2=data2[pix-=4])+data[pix]-256) < 0) || (r2 < 128 && r3 < 0)) {
705 if ( ((g3 = 2*(g2=data2[pix1=pix+1])+data[pix1]-256) < 0) || (g2 < 128 && g3 < 0)) {
713 if ( ((b3 = 2*(b2=data2[pix2=pix+2])+data[pix2]-256) < 0) || (b2 < 128 && b3 < 0)) {
727 if ((r2=data2[pix-=4]) < 128) {
729 if ((r3 = 255 - ((255-data[pix])<<8) / (2*r2)) < 0)
736 } else if ((r3 = (r4=2*r2-256)) < 255) {
737 if ((r3 = (data[pix]<<8)/(255-r4)) > 255)
748 if ((g2=data2[pix1=pix+1]) < 128) {
750 if ((g3 = 255 - ((255-data[pix1])<<8) / (2*g2)) < 0)
757 } else if ((g3 = (g4=2*g2-256)) < 255) {
758 if ((g3 = (data[pix1]<<8)/(255-g4)) > 255)
769 if ((b2=data2[pix2=pix+2]) < 128) {
771 if ((b3 = 255 - ((255-data[pix2])<<8) / (2*b2)) < 0)
778 } else if ((b3 = (b4=2*b2-256)) < 255) {
779 if ((b3 = (data[pix2]<<8)/(255-b4)) > 255)
795 if ((r2=data2[pix-=4]) < 128)
796 if ((r1=data[pix]) < (r4=2*r2))
801 if ((r1=data[pix]) > (r4=2*r2-256))
806 if ((g2=data2[pix1=pix+1]) < 128)
807 if ((g1=data[pix1]) < (g4=2*g2))
812 if ((g1=data[pix1]) > (g4=2*g2-256))
817 if ((r2=data2[pix2=pix+2]) < 128)
818 if ((r1=data[pix2]) < (r4=2*r2))
823 if ((r1=data[pix2]) > (r4=2*r2-256))
833 if ((r2 = data2[pix-=4]) < 128)
834 if (255 - ((255-data[pix])<<8)/(2*r2) < 128 || r2 == 0)
838 else if ((r4=2*r2-256) < 255 && (data[pix]<<8)/(255-r4) < 128)
843 if ((g2 = data2[pix1=pix+1]) < 128)
844 if (255 - ((255-data[pix1])<<8)/(2*g2) < 128 || g2 == 0)
848 else if ((g4=2*g2-256) < 255 && (data[pix1]<<8)/(255-g4) < 128)
853 if ((b2 = data2[pix2=pix+2]) < 128)
854 if (255 - ((255-data[pix2])<<8)/(2*b2) < 128 || b2 == 0)
858 else if ((b4=2*b2-256) < 255 && (data[pix2]<<8)/(255-b4) < 128)
868 otherCtx.putImageData(dataDesc2,0,0);
870 var ctx = params.canvas.getContext("2d");
872 ctx.globalAlpha = amount;
875 0,0,rect.width,rect.height,
876 rect.left,rect.top,rect.width,rect.height
884 checkSupport : function() {
885 return Pixastic.Client.hasCanvasImageData();
888 * Pixastic Lib - Blur filter - v0.1.0
889 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
890 * License: [http://www.pixastic.com/lib/license.txt]
893 Pixastic.Actions.blur = {
894 process : function(params) {
896 if (typeof params.options.fixMargin == "undefined")
897 params.options.fixMargin = true;
899 if (Pixastic.Client.hasCanvasImageData()) {
900 var data = Pixastic.prepareData(params);
901 var dataCopy = Pixastic.prepareData(params, true)
918 for (var i=0;i<3;i++) {
919 for (var j=0;j<3;j++) {
920 weight += kernel[i][j];
924 weight = 1 / (weight*2);
926 var rect = params.options.rect;
933 var offsetY = (y-1)*w4;
935 var prevY = (y == 1) ? 0 : y-2;
936 var nextY = (y == h) ? y - 1 : y;
938 var offsetYPrev = prevY*w*4;
939 var offsetYNext = nextY*w*4;
943 var offset = offsetY + (x*4-4);
945 var offsetPrev = offsetYPrev + ((x == 1) ? 0 : x-2) * 4;
946 var offsetNext = offsetYNext + ((x == w) ? x-1 : x) * 4;
950 dataCopy[offsetPrev - 4]
951 + dataCopy[offsetPrev+4]
952 + dataCopy[offsetNext - 4]
953 + dataCopy[offsetNext+4]
956 (dataCopy[offsetPrev]
959 + dataCopy[offsetNext]) * 2
960 + dataCopy[offset] * 4
965 dataCopy[offsetPrev - 3]
966 + dataCopy[offsetPrev+5]
967 + dataCopy[offsetNext - 3]
968 + dataCopy[offsetNext+5]
971 (dataCopy[offsetPrev+1]
974 + dataCopy[offsetNext+1]) * 2
975 + dataCopy[offset+1] * 4
980 dataCopy[offsetPrev - 2]
981 + dataCopy[offsetPrev+6]
982 + dataCopy[offsetNext - 2]
983 + dataCopy[offsetNext+6]
986 (dataCopy[offsetPrev+2]
989 + dataCopy[offsetNext+2]) * 2
990 + dataCopy[offset+2] * 4
998 } else if (Pixastic.Client.isIE()) {
999 params.image.style.filter += " progid:DXImageTransform.Microsoft.Blur(pixelradius=1.5)";
1001 if (params.options.fixMargin) {
1002 params.image.style.marginLeft = (parseInt(params.image.style.marginLeft,10)||0) - 2 + "px";
1003 params.image.style.marginTop = (parseInt(params.image.style.marginTop,10)||0) - 2 + "px";
1009 checkSupport : function() {
1010 return (Pixastic.Client.hasCanvasImageData() || Pixastic.Client.isIE());
1013 * Pixastic Lib - Blur Fast - v0.1.1
1014 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
1015 * License: [http://www.pixastic.com/lib/license.txt]
1018 Pixastic.Actions.blurfast = {
1019 process : function(params) {
1021 var amount = parseFloat(params.options.amount)||0;
1022 var clear = !!(params.options.clear && params.options.clear != "false");
1024 amount = Math.max(0,Math.min(5,amount));
1026 if (Pixastic.Client.hasCanvas()) {
1027 var rect = params.options.rect;
1029 var ctx = params.canvas.getContext("2d");
1032 ctx.rect(rect.left, rect.top, rect.width, rect.height);
1036 var smallWidth = Math.round(params.width / scale);
1037 var smallHeight = Math.round(params.height / scale);
1039 var copy = document.createElement("canvas");
1040 copy.width = smallWidth;
1041 copy.height = smallHeight;
1044 var steps = Math.round(amount * 20);
1046 var copyCtx = copy.getContext("2d");
1047 for (var i=0;i<steps;i++) {
1048 var scaledWidth = Math.max(1,Math.round(smallWidth - i));
1049 var scaledHeight = Math.max(1,Math.round(smallHeight - i));
1051 copyCtx.clearRect(0,0,smallWidth,smallHeight);
1055 0,0,params.width,params.height,
1056 0,0,scaledWidth,scaledHeight
1060 ctx.clearRect(rect.left,rect.top,rect.width,rect.height);
1064 0,0,scaledWidth,scaledHeight,
1065 0,0,params.width,params.height
1071 params.useData = false;
1073 } else if (Pixastic.Client.isIE()) {
1074 var radius = 10 * amount;
1075 params.image.style.filter += " progid:DXImageTransform.Microsoft.Blur(pixelradius=" + radius + ")";
1077 if (params.options.fixMargin || 1) {
1078 params.image.style.marginLeft = (parseInt(params.image.style.marginLeft,10)||0) - Math.round(radius) + "px";
1079 params.image.style.marginTop = (parseInt(params.image.style.marginTop,10)||0) - Math.round(radius) + "px";
1085 checkSupport : function() {
1086 return (Pixastic.Client.hasCanvas() || Pixastic.Client.isIE());
1090 * Pixastic Lib - Brightness/Contrast filter - v0.1.1
1091 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
1092 * License: [http://www.pixastic.com/lib/license.txt]
1095 Pixastic.Actions.brightness = {
1097 process : function(params) {
1099 var brightness = parseInt(params.options.brightness,10) || 0;
1100 var contrast = parseFloat(params.options.contrast)||0;
1101 var legacy = !!(params.options.legacy && params.options.legacy != "false");
1104 brightness = Math.min(150,Math.max(-150,brightness));
1106 var brightMul = 1 + Math.min(150,Math.max(-150,brightness)) / 150;
1108 contrast = Math.max(0,contrast+1);
1110 if (Pixastic.Client.hasCanvasImageData()) {
1111 var data = Pixastic.prepareData(params);
1112 var rect = params.options.rect;
1114 var h = rect.height;
1117 var pix = p*4, pix1, pix2;
1120 if (contrast != 1) {
1123 add = (brightness - 128) * contrast + 128;
1125 mul = brightMul * contrast;
1126 add = - contrast * 128 + 128;
1128 } else { // this if-then is not necessary anymore, is it?
1139 if ((r = data[pix-=4] * mul + add) > 255 )
1146 if ((g = data[pix1=pix+1] * mul + add) > 255 )
1153 if ((b = data[pix2=pix+2] * mul + add) > 255 )
1163 checkSupport : function() {
1164 return Pixastic.Client.hasCanvasImageData();
1169 * Pixastic Lib - Color adjust filter - v0.1.1
1170 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
1171 * License: [http://www.pixastic.com/lib/license.txt]
1174 Pixastic.Actions.coloradjust = {
1176 process : function(params) {
1177 var red = parseFloat(params.options.red) || 0;
1178 var green = parseFloat(params.options.green) || 0;
1179 var blue = parseFloat(params.options.blue) || 0;
1181 red = Math.round(red*255);
1182 green = Math.round(green*255);
1183 blue = Math.round(blue*255);
1185 if (Pixastic.Client.hasCanvasImageData()) {
1186 var data = Pixastic.prepareData(params);
1187 var rect = params.options.rect;
1189 var p = rect.width*rect.height;
1190 var pix = p*4, pix1, pix2;
1197 if ((r = data[pix] + red) < 0 )
1206 if ((g = data[pix1=pix+1] + green) < 0 )
1215 if ((b = data[pix2=pix+2] + blue) < 0 )
1226 checkSupport : function() {
1227 return (Pixastic.Client.hasCanvasImageData());
1231 * Pixastic Lib - Histogram - v0.1.0
1232 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
1233 * License: [http://www.pixastic.com/lib/license.txt]
1237 Pixastic.Actions.colorhistogram = {
1239 array256 : function(default_value) {
1241 for (var i=0; i<256; i++) { arr[i] = default_value; }
1245 process : function(params) {
1247 if (typeof params.options.returnValue != "object") {
1248 params.options.returnValue = {rvals:[], gvals:[], bvals:[]};
1250 var paint = !!(params.options.paint);
1252 var returnValue = params.options.returnValue;
1253 if (typeof returnValue.values != "array") {
1254 returnValue.rvals = [];
1255 returnValue.gvals = [];
1256 returnValue.bvals = [];
1259 if (Pixastic.Client.hasCanvasImageData()) {
1260 var data = Pixastic.prepareData(params);
1261 params.useData = false;
1263 var rvals = this.array256(0);
1264 var gvals = this.array256(0);
1265 var bvals = this.array256(0);
1267 var rect = params.options.rect;
1269 var p = rect.width*rect.height;
1272 rvals[data[pix-=4]]++;
1273 gvals[data[pix+1]]++;
1274 bvals[data[pix+2]]++;
1277 returnValue.rvals = rvals;
1278 returnValue.gvals = gvals;
1279 returnValue.bvals = bvals;
1282 var ctx = params.canvas.getContext("2d");
1283 var vals = [rvals, gvals, bvals];
1284 for (var v=0;v<3;v++) {
1285 var yoff = (v+1) * params.height / 3;
1287 for (var i=0;i<256;i++) {
1288 if (vals[v][i] > maxValue)
1289 maxValue = vals[v][i];
1291 var heightScale = params.height / 3 / maxValue;
1292 var widthScale = params.width / 256;
1293 if (v==0) ctx.fillStyle = "rgba(255,0,0,0.5)";
1294 else if (v==1) ctx.fillStyle = "rgba(0,255,0,0.5)";
1295 else if (v==2) ctx.fillStyle = "rgba(0,0,255,0.5)";
1296 for (var i=0;i<256;i++) {
1298 i * widthScale, params.height - heightScale * vals[v][i] - params.height + yoff,
1299 widthScale, vals[v][i] * heightScale
1308 checkSupport : function() {
1309 return Pixastic.Client.hasCanvasImageData();
1312 * Pixastic Lib - Crop - v0.1.1
1313 * Copyright (c) 2008-2009 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
1314 * License: [http://www.pixastic.com/lib/license.txt]
1317 Pixastic.Actions.crop = {
1318 process : function(params) {
1319 if (Pixastic.Client.hasCanvas()) {
1320 var rect = params.options.rect;
1322 var width = rect.width;
1323 var height = rect.height;
1325 var left = rect.left;
1327 if (typeof params.options.left != "undefined")
1328 left = parseInt(params.options.left,10);
1329 if (typeof params.options.top != "undefined")
1330 top = parseInt(params.options.top,10);
1331 if (typeof params.options.height != "undefined")
1332 width = parseInt(params.options.width,10);
1333 if (typeof params.options.height != "undefined")
1334 height = parseInt(params.options.height,10);
1336 if (left < 0) left = 0;
1337 if (left > params.width-1) left = params.width-1;
1339 if (top < 0) top = 0;
1340 if (top > params.height-1) top = params.height-1;
1342 if (width < 1) width = 1;
1343 if (left + width > params.width)
1344 width = params.width - left;
1346 if (height < 1) height = 1;
1347 if (top + height > params.height)
1348 height = params.height - top;
1350 var copy = document.createElement("canvas");
1351 copy.width = params.width;
1352 copy.height = params.height;
1353 copy.getContext("2d").drawImage(params.canvas,0,0);
1355 params.canvas.width = width;
1356 params.canvas.height = height;
1357 params.canvas.getContext("2d").clearRect(0,0,width,height);
1359 params.canvas.getContext("2d").drawImage(copy,
1360 left,top,width,height,
1364 params.useData = false;
1368 checkSupport : function() {
1369 return Pixastic.Client.hasCanvas();
1375 * Pixastic Lib - Desaturation filter - v0.1.1
1376 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
1377 * License: [http://www.pixastic.com/lib/license.txt]
1380 Pixastic.Actions.desaturate = {
1382 process : function(params) {
1383 var useAverage = !!(params.options.average && params.options.average != "false");
1385 if (Pixastic.Client.hasCanvasImageData()) {
1386 var data = Pixastic.prepareData(params);
1387 var rect = params.options.rect;
1389 var h = rect.height;
1392 var pix = p*4, pix1, pix2;
1396 data[pix-=4] = data[pix1=pix+1] = data[pix2=pix+2] = (data[pix]+data[pix1]+data[pix2])/3
1399 data[pix-=4] = data[pix1=pix+1] = data[pix2=pix+2] = (data[pix]*0.3 + data[pix1]*0.59 + data[pix2]*0.11);
1402 } else if (Pixastic.Client.isIE()) {
1403 params.image.style.filter += " gray";
1407 checkSupport : function() {
1408 return (Pixastic.Client.hasCanvasImageData() || Pixastic.Client.isIE());
1411 * Pixastic Lib - Edge detection filter - v0.1.1
1412 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
1413 * License: [http://www.pixastic.com/lib/license.txt]
1416 Pixastic.Actions.edges = {
1417 process : function(params) {
1419 var mono = !!(params.options.mono && params.options.mono != "false");
1420 var invert = !!(params.options.invert && params.options.invert != "false");
1422 if (Pixastic.Client.hasCanvasImageData()) {
1423 var data = Pixastic.prepareData(params);
1424 var dataCopy = Pixastic.prepareData(params, true)
1435 var rect = params.options.rect;
1437 var h = rect.height;
1442 var offsetY = (y-1)*w4;
1444 var nextY = (y == h) ? y - 1 : y;
1445 var prevY = (y == 1) ? 0 : y-2;
1447 var offsetYPrev = prevY*w*4;
1448 var offsetYNext = nextY*w*4;
1452 var offset = offsetY + (x*4-4);
1454 var offsetPrev = offsetYPrev + ((x == 1) ? 0 : x-2) * 4;
1455 var offsetNext = offsetYNext + ((x == w) ? x-1 : x) * 4;
1457 var r = ((dataCopy[offsetPrev-4]
1458 + dataCopy[offsetPrev]
1459 + dataCopy[offsetPrev+4]
1460 + dataCopy[offset-4]
1461 + dataCopy[offset+4]
1462 + dataCopy[offsetNext-4]
1463 + dataCopy[offsetNext]
1464 + dataCopy[offsetNext+4]) * c
1469 var g = ((dataCopy[offsetPrev-3]
1470 + dataCopy[offsetPrev+1]
1471 + dataCopy[offsetPrev+5]
1472 + dataCopy[offset-3]
1473 + dataCopy[offset+5]
1474 + dataCopy[offsetNext-3]
1475 + dataCopy[offsetNext+1]
1476 + dataCopy[offsetNext+5]) * c
1477 + dataCopy[offset+1])
1480 var b = ((dataCopy[offsetPrev-2]
1481 + dataCopy[offsetPrev+2]
1482 + dataCopy[offsetPrev+6]
1483 + dataCopy[offset-2]
1484 + dataCopy[offset+6]
1485 + dataCopy[offsetNext-2]
1486 + dataCopy[offsetNext+2]
1487 + dataCopy[offsetNext+6]) * c
1488 + dataCopy[offset+2])
1492 var brightness = (r*0.3 + g*0.59 + b*0.11)||0;
1493 if (invert) brightness = 255 - brightness;
1494 if (brightness < 0 ) brightness = 0;
1495 if (brightness > 255 ) brightness = 255;
1496 r = g = b = brightness;
1506 if (r > 255 ) r = 255;
1507 if (g > 255 ) g = 255;
1508 if (b > 255 ) b = 255;
1521 checkSupport : function() {
1522 return Pixastic.Client.hasCanvasImageData();
1525 * Pixastic Lib - Edge detection 2 - v0.1.0
1526 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
1527 * License: [http://www.pixastic.com/lib/license.txt]
1529 * Contribution by Oliver Hunt (http://nerget.com/, http://nerget.com/canvas/edgeDetection.js). Thanks Oliver!
1533 Pixastic.Actions.edges2 = {
1534 process : function(params) {
1536 if (Pixastic.Client.hasCanvasImageData()) {
1537 var data = Pixastic.prepareData(params);
1538 var dataCopy = Pixastic.prepareData(params, true)
1540 var rect = params.options.rect;
1542 var h = rect.height;
1545 var pixel = w4 + 4; // Start at (1,1)
1548 for (var y = 1; y < hm1; ++y) {
1549 // Prepare initial cached values for current row
1550 var centerRow = pixel - 4;
1551 var priorRow = centerRow - w4;
1552 var nextRow = centerRow + w4;
1554 var r1 = - dataCopy[priorRow] - dataCopy[centerRow] - dataCopy[nextRow];
1555 var g1 = - dataCopy[++priorRow] - dataCopy[++centerRow] - dataCopy[++nextRow];
1556 var b1 = - dataCopy[++priorRow] - dataCopy[++centerRow] - dataCopy[++nextRow];
1558 var rp = dataCopy[priorRow += 2];
1559 var gp = dataCopy[++priorRow];
1560 var bp = dataCopy[++priorRow];
1562 var rc = dataCopy[centerRow += 2];
1563 var gc = dataCopy[++centerRow];
1564 var bc = dataCopy[++centerRow];
1566 var rn = dataCopy[nextRow += 2];
1567 var gn = dataCopy[++nextRow];
1568 var bn = dataCopy[++nextRow];
1570 var r2 = - rp - rc - rn;
1571 var g2 = - gp - gc - gn;
1572 var b2 = - bp - bc - bn;
1574 // Main convolution loop
1575 for (var x = 1; x < wm1; ++x) {
1576 centerRow = pixel + 4;
1577 priorRow = centerRow - w4;
1578 nextRow = centerRow + w4;
1580 var r = 127 + r1 - rp - (rc * -8) - rn;
1581 var g = 127 + g1 - gp - (gc * -8) - gn;
1582 var b = 127 + b1 - bp - (bc * -8) - bn;
1588 rp = dataCopy[ priorRow];
1589 gp = dataCopy[++priorRow];
1590 bp = dataCopy[++priorRow];
1592 rc = dataCopy[ centerRow];
1593 gc = dataCopy[++centerRow];
1594 bc = dataCopy[++centerRow];
1596 rn = dataCopy[ nextRow];
1597 gn = dataCopy[++nextRow];
1598 bn = dataCopy[++nextRow];
1600 r += (r2 = - rp - rc - rn);
1601 g += (g2 = - gp - gc - gn);
1602 b += (b2 = - bp - bc - bn);
1604 if (r > 255) r = 255;
1605 if (g > 255) g = 255;
1606 if (b > 255) b = 255;
1614 //data[++pixel] = 255; // alpha
1623 checkSupport : function() {
1624 return Pixastic.Client.hasCanvasImageData();
1627 * Pixastic Lib - Emboss filter - v0.1.0
1628 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
1629 * License: [http://www.pixastic.com/lib/license.txt]
1632 Pixastic.Actions.emboss = {
1633 process : function(params) {
1635 var strength = parseFloat(params.options.strength)||1;
1636 var greyLevel = typeof params.options.greyLevel != "undefined" ? parseInt(params.options.greyLevel) : 180;
1637 var direction = params.options.direction||"topleft";
1638 var blend = !!(params.options.blend && params.options.blend != "false");
1643 switch (direction) {
1644 case "topleft": // top left
1652 case "topright": // top right
1656 case "right": // right
1660 case "bottomright": // bottom right
1664 case "bottom": // bottom
1668 case "bottomleft": // bottom left
1672 case "left": // left
1678 if (Pixastic.Client.hasCanvasImageData()) {
1679 var data = Pixastic.prepareData(params);
1680 var dataCopy = Pixastic.prepareData(params, true)
1682 var invertAlpha = !!params.options.invertAlpha;
1683 var rect = params.options.rect;
1685 var h = rect.height;
1690 var offsetY = (y-1)*w4;
1693 if (y + otherY < 1) otherY = 0;
1694 if (y + otherY > h) otherY = 0;
1696 var offsetYOther = (y-1+otherY)*w*4;
1700 var offset = offsetY + (x-1)*4;
1703 if (x + otherX < 1) otherX = 0;
1704 if (x + otherX > w) otherX = 0;
1706 var offsetOther = offsetYOther + (x-1+otherX)*4;
1708 var dR = dataCopy[offset] - dataCopy[offsetOther];
1709 var dG = dataCopy[offset+1] - dataCopy[offsetOther+1];
1710 var dB = dataCopy[offset+2] - dataCopy[offsetOther+2];
1713 var absDif = dif > 0 ? dif : -dif;
1715 var absG = dG > 0 ? dG : -dG;
1716 var absB = dB > 0 ? dB : -dB;
1718 if (absG > absDif) {
1721 if (absB > absDif) {
1728 var r = data[offset] + dif;
1729 var g = data[offset+1] + dif;
1730 var b = data[offset+2] + dif;
1732 data[offset] = (r > 255) ? 255 : (r < 0 ? 0 : r);
1733 data[offset+1] = (g > 255) ? 255 : (g < 0 ? 0 : g);
1734 data[offset+2] = (b > 255) ? 255 : (b < 0 ? 0 : b);
1736 var grey = greyLevel - dif;
1739 } else if (grey > 255) {
1743 data[offset] = data[offset+1] = data[offset+2] = grey;
1750 } else if (Pixastic.Client.isIE()) {
1751 params.image.style.filter += " progid:DXImageTransform.Microsoft.emboss()";
1755 checkSupport : function() {
1756 return (Pixastic.Client.hasCanvasImageData() || Pixastic.Client.isIE());
1761 * Pixastic Lib - Flip - v0.1.0
1762 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
1763 * License: [http://www.pixastic.com/lib/license.txt]
1766 Pixastic.Actions.flip = {
1767 process : function(params) {
1768 var rect = params.options.rect;
1769 var copyCanvas = document.createElement("canvas");
1770 copyCanvas.width = rect.width;
1771 copyCanvas.height = rect.height;
1772 copyCanvas.getContext("2d").drawImage(params.image, rect.left, rect.top, rect.width, rect.height, 0, 0, rect.width, rect.height);
1774 var ctx = params.canvas.getContext("2d");
1775 ctx.clearRect(rect.left, rect.top, rect.width, rect.height);
1777 if (params.options.axis == "horizontal") {
1779 ctx.drawImage(copyCanvas, -rect.left-rect.width, rect.top, rect.width, rect.height)
1782 ctx.drawImage(copyCanvas, rect.left, -rect.top-rect.height, rect.width, rect.height)
1785 params.useData = false;
1789 checkSupport : function() {
1790 return Pixastic.Client.hasCanvas();
1795 * Pixastic Lib - Horizontal flip - v0.1.0
1796 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
1797 * License: [http://www.pixastic.com/lib/license.txt]
1800 Pixastic.Actions.fliph = {
1801 process : function(params) {
1802 if (Pixastic.Client.hasCanvas()) {
1803 var rect = params.options.rect;
1804 var copyCanvas = document.createElement("canvas");
1805 copyCanvas.width = rect.width;
1806 copyCanvas.height = rect.height;
1807 copyCanvas.getContext("2d").drawImage(params.image, rect.left, rect.top, rect.width, rect.height, 0, 0, rect.width, rect.height);
1809 var ctx = params.canvas.getContext("2d");
1810 ctx.clearRect(rect.left, rect.top, rect.width, rect.height);
1812 ctx.drawImage(copyCanvas, -rect.left-rect.width, rect.top, rect.width, rect.height)
1813 params.useData = false;
1817 } else if (Pixastic.Client.isIE()) {
1818 params.image.style.filter += " fliph";
1822 checkSupport : function() {
1823 return (Pixastic.Client.hasCanvas() || Pixastic.Client.isIE());
1828 * Pixastic Lib - Vertical flip - v0.1.0
1829 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
1830 * License: [http://www.pixastic.com/lib/license.txt]
1833 Pixastic.Actions.flipv = {
1834 process : function(params) {
1835 if (Pixastic.Client.hasCanvas()) {
1836 var rect = params.options.rect;
1837 var copyCanvas = document.createElement("canvas");
1838 copyCanvas.width = rect.width;
1839 copyCanvas.height = rect.height;
1840 copyCanvas.getContext("2d").drawImage(params.image, rect.left, rect.top, rect.width, rect.height, 0, 0, rect.width, rect.height);
1842 var ctx = params.canvas.getContext("2d");
1843 ctx.clearRect(rect.left, rect.top, rect.width, rect.height);
1845 ctx.drawImage(copyCanvas, rect.left, -rect.top-rect.height, rect.width, rect.height)
1846 params.useData = false;
1850 } else if (Pixastic.Client.isIE()) {
1851 params.image.style.filter += " flipv";
1855 checkSupport : function() {
1856 return (Pixastic.Client.hasCanvas() || Pixastic.Client.isIE());
1861 * Pixastic Lib - Glow - v0.1.0
1862 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
1863 * License: [http://www.pixastic.com/lib/license.txt]
1867 Pixastic.Actions.glow = {
1868 process : function(params) {
1870 var amount = (parseFloat(params.options.amount)||0);
1871 var blurAmount = parseFloat(params.options.radius)||0;
1873 amount = Math.min(1,Math.max(0,amount));
1874 blurAmount = Math.min(5,Math.max(0,blurAmount));
1876 if (Pixastic.Client.hasCanvasImageData()) {
1877 var rect = params.options.rect;
1879 var blurCanvas = document.createElement("canvas");
1880 blurCanvas.width = params.width;
1881 blurCanvas.height = params.height;
1882 var blurCtx = blurCanvas.getContext("2d");
1883 blurCtx.drawImage(params.canvas,0,0);
1886 var smallWidth = Math.round(params.width / scale);
1887 var smallHeight = Math.round(params.height / scale);
1889 var copy = document.createElement("canvas");
1890 copy.width = smallWidth;
1891 copy.height = smallHeight;
1894 var steps = Math.round(blurAmount * 20);
1896 var copyCtx = copy.getContext("2d");
1897 for (var i=0;i<steps;i++) {
1898 var scaledWidth = Math.max(1,Math.round(smallWidth - i));
1899 var scaledHeight = Math.max(1,Math.round(smallHeight - i));
1901 copyCtx.clearRect(0,0,smallWidth,smallHeight);
1905 0,0,params.width,params.height,
1906 0,0,scaledWidth,scaledHeight
1909 blurCtx.clearRect(0,0,params.width,params.height);
1913 0,0,scaledWidth,scaledHeight,
1914 0,0,params.width,params.height
1918 var data = Pixastic.prepareData(params);
1919 var blurData = Pixastic.prepareData({canvas:blurCanvas,options:params.options});
1921 var h = rect.height;
1925 var offsetY = (y-1)*w4;
1928 var offset = offsetY + (x*4-4);
1930 var r = data[offset] + amount * blurData[offset];
1931 var g = data[offset+1] + amount * blurData[offset+1];
1932 var b = data[offset+2] + amount * blurData[offset+2];
1934 if (r > 255) r = 255;
1935 if (g > 255) g = 255;
1936 if (b > 255) b = 255;
1951 checkSupport : function() {
1952 return Pixastic.Client.hasCanvasImageData();
1959 * Pixastic Lib - Histogram - v0.1.0
1960 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
1961 * License: [http://www.pixastic.com/lib/license.txt]
1964 Pixastic.Actions.histogram = {
1965 process : function(params) {
1967 var average = !!(params.options.average && params.options.average != "false");
1968 var paint = !!(params.options.paint && params.options.paint != "false");
1969 var color = params.options.color || "rgba(255,255,255,0.5)";
1971 if (typeof params.options.returnValue != "object") {
1972 params.options.returnValue = {values:[]};
1974 var returnValue = params.options.returnValue;
1975 if (typeof returnValue.values != "array") {
1976 returnValue.values = [];
1978 values = returnValue.values;
1980 if (Pixastic.Client.hasCanvasImageData()) {
1981 var data = Pixastic.prepareData(params);
1982 params.useData = false;
1984 for (var i=0;i<256;i++) {
1988 var rect = params.options.rect;
1990 var h = rect.height;
1994 var offsetY = (y-1)*w4;
1997 var offset = offsetY + (x*4-4);
1998 var brightness = average ?
1999 Math.round((data[offset]+data[offset+1]+data[offset+2])/3)
2000 : Math.round(data[offset]*0.3 + data[offset+1]*0.59 + data[offset+2]*0.11);
2001 values[brightness]++;
2008 for (var i=0;i<256;i++) {
2009 if (values[i] > maxValue) {
2010 maxValue = values[i];
2013 var heightScale = params.height / maxValue;
2014 var widthScale = params.width / 256;
2015 var ctx = params.canvas.getContext("2d");
2016 ctx.fillStyle = color;
2017 for (var i=0;i<256;i++) {
2019 i * widthScale, params.height - heightScale * values[i],
2020 widthScale, values[i] * heightScale
2025 returnValue.values = values;
2030 checkSupport : function() {
2031 return Pixastic.Client.hasCanvasImageData();
2035 * Pixastic Lib - HSL Adjust - v0.1.0
2036 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
2037 * License: [http://www.pixastic.com/lib/license.txt]
2040 Pixastic.Actions.hsl = {
2041 process : function(params) {
2043 var hue = parseInt(params.options.hue,10)||0;
2044 var saturation = (parseInt(params.options.saturation,10)||0) / 100;
2045 var lightness = (parseInt(params.options.lightness,10)||0) / 100;
2048 // this seems to give the same result as Photoshop
2049 if (saturation < 0) {
2050 var satMul = 1+saturation;
2052 var satMul = 1+saturation*2;
2055 hue = (hue%360) / 360;
2058 var rgbDiv = 1 / 255;
2060 var light255 = lightness * 255;
2061 var lightp1 = 1 + lightness;
2062 var lightm1 = 1 - lightness;
2063 if (Pixastic.Client.hasCanvasImageData()) {
2064 var data = Pixastic.prepareData(params);
2066 var rect = params.options.rect;
2068 var h = rect.height;
2074 var offsetY = (y-1)*w4;
2077 var offset = offsetY + (x*4-4);
2079 var r = data[offset];
2080 var g = data[offset+1];
2081 var b = data[offset+2];
2083 if (hue != 0 || saturation != 0) {
2084 // ok, here comes rgb to hsl + adjust + hsl to rgb, all in one jumbled mess.
2085 // It's not so pretty, but it's been optimized to get somewhat decent performance.
2086 // The transforms were originally adapted from the ones found in Graphics Gems, but have been heavily modified.
2094 var l = (ms+vs)/255 * 0.5;
2098 var s = vm / (vs+ms) * satMul;
2100 var v = (l * (1+s));
2102 var s = vm / (510-vs-ms) * satMul;
2104 var v = (l+s - l*s);
2108 var h = 5 + ((vs-b)/vm) + hue6;
2110 var h = 1 - ((vs-g)/vm) + hue6;
2111 } else if (g == vs) {
2113 var h = 1 + ((vs-r)/vm) + hue6;
2115 var h = 3 - ((vs-b)/vm) + hue6;
2118 var h = 3 + ((vs-g)/vm) + hue6;
2120 var h = 5 - ((vs-r)/vm) + hue6;
2127 case 0: r = v*255; g = (m+((v-m)*(h-sextant)))*255; b = m*255; break;
2128 case 1: r = (v-((v-m)*(h-sextant)))*255; g = v*255; b = m*255; break;
2129 case 2: r = m*255; g = v*255; b = (m+((v-m)*(h-sextant)))*255; break;
2130 case 3: r = m*255; g = (v-((v-m)*(h-sextant)))*255; b = v*255; break;
2131 case 4: r = (m+((v-m)*(h-sextant)))*255; g = m*255; b = v*255; break;
2132 case 5: r = v*255; g = m*255; b = (v-((v-m)*(h-sextant)))*255; break;
2138 if (lightness < 0) {
2142 } else if (lightness > 0) {
2143 r = r * lightm1 + light255;
2144 g = g * lightm1 + light255;
2145 b = b * lightm1 + light255;
2151 if (r > 255) r = 255;
2152 if (g > 255) g = 255;
2153 if (b > 255) b = 255;
2164 checkSupport : function() {
2165 return Pixastic.Client.hasCanvasImageData();
2170 * Pixastic Lib - Invert filter - v0.1.0
2171 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
2172 * License: [http://www.pixastic.com/lib/license.txt]
2175 Pixastic.Actions.invert = {
2176 process : function(params) {
2177 if (Pixastic.Client.hasCanvasImageData()) {
2178 var data = Pixastic.prepareData(params);
2180 var invertAlpha = !!params.options.invertAlpha;
2181 var rect = params.options.rect;
2183 var h = rect.height;
2188 var offsetY = (y-1)*w4;
2191 var offset = offsetY + (x-1)*4;
2192 data[offset] = 255 - data[offset];
2193 data[offset+1] = 255 - data[offset+1];
2194 data[offset+2] = 255 - data[offset+2];
2195 if (invertAlpha) data[offset+3] = 255 - data[offset+3];
2200 } else if (Pixastic.Client.isIE()) {
2201 params.image.style.filter += " invert";
2205 checkSupport : function() {
2206 return (Pixastic.Client.hasCanvasImageData() || Pixastic.Client.isIE());
2210 * Pixastic Lib - Laplace filter - v0.1.0
2211 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
2212 * License: [http://www.pixastic.com/lib/license.txt]
2215 Pixastic.Actions.laplace = {
2216 process : function(params) {
2219 var invert = !!(params.options.invert && params.options.invert != "false");
2220 var contrast = parseFloat(params.options.edgeStrength)||0;
2222 var greyLevel = parseInt(params.options.greyLevel)||0;
2224 contrast = -contrast;
2226 if (Pixastic.Client.hasCanvasImageData()) {
2227 var data = Pixastic.prepareData(params);
2228 var dataCopy = Pixastic.prepareData(params, true)
2238 var rect = params.options.rect;
2240 var h = rect.height;
2245 var offsetY = (y-1)*w4;
2247 var nextY = (y == h) ? y - 1 : y;
2248 var prevY = (y == 1) ? 0 : y-2;
2250 var offsetYPrev = prevY*w*4;
2251 var offsetYNext = nextY*w*4;
2255 var offset = offsetY + (x*4-4);
2257 var offsetPrev = offsetYPrev + ((x == 1) ? 0 : x-2) * 4;
2258 var offsetNext = offsetYNext + ((x == w) ? x-1 : x) * 4;
2260 var r = ((-dataCopy[offsetPrev-4]
2261 - dataCopy[offsetPrev]
2262 - dataCopy[offsetPrev+4]
2263 - dataCopy[offset-4]
2264 - dataCopy[offset+4]
2265 - dataCopy[offsetNext-4]
2266 - dataCopy[offsetNext]
2267 - dataCopy[offsetNext+4])
2268 + dataCopy[offset] * 8)
2271 var g = ((-dataCopy[offsetPrev-3]
2272 - dataCopy[offsetPrev+1]
2273 - dataCopy[offsetPrev+5]
2274 - dataCopy[offset-3]
2275 - dataCopy[offset+5]
2276 - dataCopy[offsetNext-3]
2277 - dataCopy[offsetNext+1]
2278 - dataCopy[offsetNext+5])
2279 + dataCopy[offset+1] * 8)
2282 var b = ((-dataCopy[offsetPrev-2]
2283 - dataCopy[offsetPrev+2]
2284 - dataCopy[offsetPrev+6]
2285 - dataCopy[offset-2]
2286 - dataCopy[offset+6]
2287 - dataCopy[offsetNext-2]
2288 - dataCopy[offsetNext+2]
2289 - dataCopy[offsetNext+6])
2290 + dataCopy[offset+2] * 8)
2293 var brightness = ((r + g + b)/3) + greyLevel;
2295 if (contrast != 0) {
2296 if (brightness > 127) {
2297 brightness += ((brightness + 1) - 128) * contrast;
2298 } else if (brightness < 127) {
2299 brightness -= (brightness + 1) * contrast;
2303 brightness = 255 - brightness;
2305 if (brightness < 0 ) brightness = 0;
2306 if (brightness > 255 ) brightness = 255;
2308 data[offset] = data[offset+1] = data[offset+2] = brightness;
2316 checkSupport : function() {
2317 return Pixastic.Client.hasCanvasImageData();
2322 * Pixastic Lib - Lighten filter - v0.1.0
2323 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
2324 * License: [http://www.pixastic.com/lib/license.txt]
2327 Pixastic.Actions.lighten = {
2329 process : function(params) {
2330 var amount = parseFloat(params.options.amount) || 0;
2332 if (Pixastic.Client.hasCanvasImageData()) {
2333 var data = Pixastic.prepareData(params);
2334 var rect = params.options.rect;
2336 var h = rect.height;
2340 var offsetY = (y-1)*w4;
2343 var offset = offsetY + (x-1)*4;
2345 var r = data[offset];
2346 var g = data[offset+1];
2347 var b = data[offset+2];
2356 if (r > 255 ) r = 255;
2357 if (g > 255 ) g = 255;
2358 if (b > 255 ) b = 255;
2368 } else if (Pixastic.Client.isIE()) {
2369 var img = params.image;
2371 img.style.filter += " light()";
2372 img.filters[img.filters.length-1].addAmbient(
2376 } else if (amount > 0) {
2377 img.style.filter += " light()";
2378 img.filters[img.filters.length-1].addAmbient(
2382 img.filters[img.filters.length-1].addAmbient(
2390 checkSupport : function() {
2391 return (Pixastic.Client.hasCanvasImageData() || Pixastic.Client.isIE());
2395 * Pixastic Lib - Mosaic filter - v0.1.0
2396 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
2397 * License: [http://www.pixastic.com/lib/license.txt]
2400 Pixastic.Actions.mosaic = {
2402 process : function(params) {
2403 var blockSize = Math.max(1,parseInt(params.options.blockSize,10));
2405 if (Pixastic.Client.hasCanvasImageData()) {
2406 var rect = params.options.rect;
2408 var h = rect.height;
2412 var ctx = params.canvas.getContext("2d");
2414 var pixel = document.createElement("canvas");
2415 pixel.width = pixel.height = 1;
2416 var pixelCtx = pixel.getContext("2d");
2418 var copy = document.createElement("canvas");
2421 var copyCtx = copy.getContext("2d");
2422 copyCtx.drawImage(params.canvas,rect.left,rect.top,w,h, 0,0,w,h);
2424 for (var y=0;y<h;y+=blockSize) {
2425 for (var x=0;x<w;x+=blockSize) {
2426 var blockSizeX = blockSize;
2427 var blockSizeY = blockSize;
2429 if (blockSizeX + x > w)
2431 if (blockSizeY + y > h)
2434 pixelCtx.drawImage(copy, x, y, blockSizeX, blockSizeY, 0, 0, 1, 1);
2435 var data = pixelCtx.getImageData(0,0,1,1).data;
2436 ctx.fillStyle = "rgb(" + data[0] + "," + data[1] + "," + data[2] + ")";
2437 ctx.fillRect(rect.left + x, rect.top + y, blockSize, blockSize);
2440 params.useData = false;
2445 checkSupport : function() {
2446 return (Pixastic.Client.hasCanvasImageData());
2449 * Pixastic Lib - Noise filter - v0.1.0
2450 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
2451 * License: [http://www.pixastic.com/lib/license.txt]
2454 Pixastic.Actions.noise = {
2456 process : function(params) {
2461 if (typeof params.options.amount != "undefined")
2462 amount = parseFloat(params.options.amount)||0;
2463 if (typeof params.options.strength != "undefined")
2464 strength = parseFloat(params.options.strength)||0;
2465 if (typeof params.options.mono != "undefined")
2466 mono = !!(params.options.mono && params.options.mono != "false");
2468 amount = Math.max(0,Math.min(1,amount));
2469 strength = Math.max(0,Math.min(1,strength));
2471 var noise = 128 * strength;
2472 var noise2 = noise / 2;
2474 if (Pixastic.Client.hasCanvasImageData()) {
2475 var data = Pixastic.prepareData(params);
2476 var rect = params.options.rect;
2478 var h = rect.height;
2481 var random = Math.random;
2484 var offsetY = (y-1)*w4;
2487 var offset = offsetY + (x-1)*4;
2488 if (random() < amount) {
2490 var pixelNoise = - noise2 + random() * noise;
2491 var r = data[offset] + pixelNoise;
2492 var g = data[offset+1] + pixelNoise;
2493 var b = data[offset+2] + pixelNoise;
2495 var r = data[offset] - noise2 + (random() * noise);
2496 var g = data[offset+1] - noise2 + (random() * noise);
2497 var b = data[offset+2] - noise2 + (random() * noise);
2503 if (r > 255 ) r = 255;
2504 if (g > 255 ) g = 255;
2505 if (b > 255 ) b = 255;
2516 checkSupport : function() {
2517 return Pixastic.Client.hasCanvasImageData();
2522 * Pixastic Lib - Posterize effect - v0.1.0
2523 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
2524 * License: [http://www.pixastic.com/lib/license.txt]
2527 Pixastic.Actions.posterize = {
2529 process : function(params) {
2532 var numLevels = 256;
2533 if (typeof params.options.levels != "undefined")
2534 numLevels = parseInt(params.options.levels,10)||1;
2536 if (Pixastic.Client.hasCanvasImageData()) {
2537 var data = Pixastic.prepareData(params);
2539 numLevels = Math.max(2,Math.min(256,numLevels));
2541 var numAreas = 256 / numLevels;
2542 var numValues = 256 / (numLevels-1);
2544 var rect = params.options.rect;
2546 var h = rect.height;
2550 var offsetY = (y-1)*w4;
2553 var offset = offsetY + (x-1)*4;
2555 var r = numValues * ((data[offset] / numAreas)>>0);
2556 var g = numValues * ((data[offset+1] / numAreas)>>0);
2557 var b = numValues * ((data[offset+2] / numAreas)>>0);
2559 if (r > 255) r = 255;
2560 if (g > 255) g = 255;
2561 if (b > 255) b = 255;
2572 checkSupport : function() {
2573 return Pixastic.Client.hasCanvasImageData();
2579 * Pixastic Lib - Pointillize filter - v0.1.0
2580 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
2581 * License: [http://www.pixastic.com/lib/license.txt]
2584 Pixastic.Actions.pointillize = {
2586 process : function(params) {
2587 var radius = Math.max(1,parseInt(params.options.radius,10));
2588 var density = Math.min(5,Math.max(0,parseFloat(params.options.density)||0));
2589 var noise = Math.max(0,parseFloat(params.options.noise)||0);
2590 var transparent = !!(params.options.transparent && params.options.transparent != "false");
2592 if (Pixastic.Client.hasCanvasImageData()) {
2593 var rect = params.options.rect;
2595 var h = rect.height;
2599 var ctx = params.canvas.getContext("2d");
2600 var canvasWidth = params.canvas.width;
2601 var canvasHeight = params.canvas.height;
2603 var pixel = document.createElement("canvas");
2604 pixel.width = pixel.height = 1;
2605 var pixelCtx = pixel.getContext("2d");
2607 var copy = document.createElement("canvas");
2610 var copyCtx = copy.getContext("2d");
2611 copyCtx.drawImage(params.canvas,rect.left,rect.top,w,h, 0,0,w,h);
2613 var diameter = radius * 2;
2616 ctx.clearRect(rect.left, rect.top, rect.width, rect.height);
2618 var noiseRadius = radius * noise;
2620 var dist = 1 / density;
2622 for (var y=0;y<h+radius;y+=diameter*dist) {
2623 for (var x=0;x<w+radius;x+=diameter*dist) {
2624 rndX = noise ? (x+((Math.random()*2-1) * noiseRadius))>>0 : x;
2625 rndY = noise ? (y+((Math.random()*2-1) * noiseRadius))>>0 : y;
2627 var pixX = rndX - radius;
2628 var pixY = rndY - radius;
2629 if (pixX < 0) pixX = 0;
2630 if (pixY < 0) pixY = 0;
2632 var cx = rndX + rect.left;
2633 var cy = rndY + rect.top;
2635 if (cx > canvasWidth) cx = canvasWidth;
2637 if (cy > canvasHeight) cy = canvasHeight;
2639 var diameterX = diameter;
2640 var diameterY = diameter;
2642 if (diameterX + pixX > w)
2643 diameterX = w - pixX;
2644 if (diameterY + pixY > h)
2645 diameterY = h - pixY;
2646 if (diameterX < 1) diameterX = 1;
2647 if (diameterY < 1) diameterY = 1;
2649 pixelCtx.drawImage(copy, pixX, pixY, diameterX, diameterY, 0, 0, 1, 1);
2650 var data = pixelCtx.getImageData(0,0,1,1).data;
2652 ctx.fillStyle = "rgb(" + data[0] + "," + data[1] + "," + data[2] + ")";
2654 ctx.arc(cx, cy, radius, 0, Math.PI*2, true);
2660 params.useData = false;
2665 checkSupport : function() {
2666 return (Pixastic.Client.hasCanvasImageData());
2669 * Pixastic Lib - Resize - v0.1.0
2670 * Copyright (c) 2009 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
2671 * License: [http://www.pixastic.com/lib/license.txt]
2674 Pixastic.Actions.resize = {
2675 process : function(params) {
2676 if (Pixastic.Client.hasCanvas()) {
2677 var width = parseInt(params.options.width,10);
2678 var height = parseInt(params.options.height,10);
2679 var canvas = params.canvas;
2681 if (width < 1) width = 1;
2682 if (width < 2) width = 2;
2684 var copy = document.createElement("canvas");
2686 copy.height = height;
2688 copy.getContext("2d").drawImage(canvas,0,0,width,height);
2689 canvas.width = width;
2690 canvas.height = height;
2692 canvas.getContext("2d").drawImage(copy,0,0);
2694 params.useData = false;
2698 checkSupport : function() {
2699 return Pixastic.Client.hasCanvas();
2705 * Pixastic Lib - Remove noise - v0.1.0
2706 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
2707 * License: [http://www.pixastic.com/lib/license.txt]
2710 Pixastic.Actions.removenoise = {
2711 process : function(params) {
2713 if (Pixastic.Client.hasCanvasImageData()) {
2714 var data = Pixastic.prepareData(params);
2716 var rect = params.options.rect;
2718 var h = rect.height;
2723 var offsetY = (y-1)*w4;
2725 var nextY = (y == h) ? y - 1 : y;
2726 var prevY = (y == 1) ? 0 : y-2;
2728 var offsetYPrev = prevY*w*4;
2729 var offsetYNext = nextY*w*4;
2733 var offset = offsetY + (x*4-4);
2735 var offsetPrev = offsetYPrev + ((x == 1) ? 0 : x-2) * 4;
2736 var offsetNext = offsetYNext + ((x == w) ? x-1 : x) * 4;
2738 var minR, maxR, minG, maxG, minB, maxB;
2740 minR = maxR = data[offsetPrev];
2741 var r1 = data[offset-4], r2 = data[offset+4], r3 = data[offsetNext];
2742 if (r1 < minR) minR = r1;
2743 if (r2 < minR) minR = r2;
2744 if (r3 < minR) minR = r3;
2745 if (r1 > maxR) maxR = r1;
2746 if (r2 > maxR) maxR = r2;
2747 if (r3 > maxR) maxR = r3;
2749 minG = maxG = data[offsetPrev+1];
2750 var g1 = data[offset-3], g2 = data[offset+5], g3 = data[offsetNext+1];
2751 if (g1 < minG) minG = g1;
2752 if (g2 < minG) minG = g2;
2753 if (g3 < minG) minG = g3;
2754 if (g1 > maxG) maxG = g1;
2755 if (g2 > maxG) maxG = g2;
2756 if (g3 > maxG) maxG = g3;
2758 minB = maxB = data[offsetPrev+2];
2759 var b1 = data[offset-2], b2 = data[offset+6], b3 = data[offsetNext+2];
2760 if (b1 < minB) minB = b1;
2761 if (b2 < minB) minB = b2;
2762 if (b3 < minB) minB = b3;
2763 if (b1 > maxB) maxB = b1;
2764 if (b2 > maxB) maxB = b2;
2765 if (b3 > maxB) maxB = b3;
2767 if (data[offset] > maxR) {
2768 data[offset] = maxR;
2769 } else if (data[offset] < minR) {
2770 data[offset] = minR;
2772 if (data[offset+1] > maxG) {
2773 data[offset+1] = maxG;
2774 } else if (data[offset+1] < minG) {
2775 data[offset+1] = minG;
2777 if (data[offset+2] > maxB) {
2778 data[offset+2] = maxB;
2779 } else if (data[offset+2] < minB) {
2780 data[offset+2] = minB;
2789 checkSupport : function() {
2790 return Pixastic.Client.hasCanvasImageData();
2793 * Pixastic Lib - Rotate - v0.1.0
2794 * Copyright (c) 2009 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
2795 * License: [http://www.pixastic.com/lib/license.txt]
2798 Pixastic.Actions.rotate = {
2799 process : function(params) {
2800 if (Pixastic.Client.hasCanvas()) {
2801 var canvas = params.canvas;
2803 var width = params.width;
2804 var height = params.height;
2806 var copy = document.createElement("canvas");
2808 copy.height = height;
2809 copy.getContext("2d").drawImage(canvas,0,0,width,height);
2811 var angle = -parseFloat(params.options.angle) * Math.PI / 180;
2813 var dimAngle = angle;
2814 if (dimAngle > Math.PI*0.5)
2815 dimAngle = Math.PI - dimAngle;
2816 if (dimAngle < -Math.PI*0.5)
2817 dimAngle = -Math.PI - dimAngle;
2819 var diag = Math.sqrt(width*width + height*height);
2821 var diagAngle1 = Math.abs(dimAngle) - Math.abs(Math.atan2(height, width));
2822 var diagAngle2 = Math.abs(dimAngle) + Math.abs(Math.atan2(height, width));
2824 var newWidth = Math.abs(Math.cos(diagAngle1) * diag);
2825 var newHeight = Math.abs(Math.sin(diagAngle2) * diag);
2827 canvas.width = newWidth;
2828 canvas.height = newHeight;
2830 var ctx = canvas.getContext("2d");
2831 ctx.translate(newWidth/2, newHeight/2);
2833 ctx.drawImage(copy,-width/2,-height/2);
2835 params.useData = false;
2839 checkSupport : function() {
2840 return Pixastic.Client.hasCanvas();
2846 * Pixastic Lib - Sepia filter - v0.1.0
2847 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
2848 * License: [http://www.pixastic.com/lib/license.txt]
2851 Pixastic.Actions.sepia = {
2853 process : function(params) {
2854 var mode = (parseInt(params.options.mode,10)||0);
2855 if (mode < 0) mode = 0;
2856 if (mode > 1) mode = 1;
2858 if (Pixastic.Client.hasCanvasImageData()) {
2859 var data = Pixastic.prepareData(params);
2860 var rect = params.options.rect;
2862 var h = rect.height;
2866 var offsetY = (y-1)*w4;
2869 var offset = offsetY + (x-1)*4;
2872 // a bit faster, but not as good
2873 var d = data[offset] * 0.299 + data[offset+1] * 0.587 + data[offset+2] * 0.114;
2879 var or = data[offset];
2880 var og = data[offset+1];
2881 var ob = data[offset+2];
2883 var r = (or * 0.393 + og * 0.769 + ob * 0.189);
2884 var g = (or * 0.349 + og * 0.686 + ob * 0.168);
2885 var b = (or * 0.272 + og * 0.534 + ob * 0.131);
2888 if (r < 0) r = 0; if (r > 255) r = 255;
2889 if (g < 0) g = 0; if (g > 255) g = 255;
2890 if (b < 0) b = 0; if (b > 255) b = 255;
2901 checkSupport : function() {
2902 return Pixastic.Client.hasCanvasImageData();
2905 * Pixastic Lib - Sharpen filter - v0.1.0
2906 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
2907 * License: [http://www.pixastic.com/lib/license.txt]
2910 Pixastic.Actions.sharpen = {
2911 process : function(params) {
2914 if (typeof params.options.amount != "undefined")
2915 strength = parseFloat(params.options.amount)||0;
2917 if (strength < 0) strength = 0;
2918 if (strength > 1) strength = 1;
2920 if (Pixastic.Client.hasCanvasImageData()) {
2921 var data = Pixastic.prepareData(params);
2922 var dataCopy = Pixastic.prepareData(params, true)
2925 var mulOther = 1 + 3*strength;
2929 [-mulOther, mul, -mulOther],
2934 for (var i=0;i<3;i++) {
2935 for (var j=0;j<3;j++) {
2936 weight += kernel[i][j];
2940 weight = 1 / weight;
2942 var rect = params.options.rect;
2944 var h = rect.height;
2952 var offsetY = (y-1)*w4;
2954 var nextY = (y == h) ? y - 1 : y;
2955 var prevY = (y == 1) ? 0 : y-2;
2957 var offsetYPrev = prevY*w4;
2958 var offsetYNext = nextY*w4;
2962 var offset = offsetY + (x*4-4);
2964 var offsetPrev = offsetYPrev + ((x == 1) ? 0 : x-2) * 4;
2965 var offsetNext = offsetYNext + ((x == w) ? x-1 : x) * 4;
2968 - dataCopy[offsetPrev]
2969 - dataCopy[offset-4]
2970 - dataCopy[offset+4]
2971 - dataCopy[offsetNext]) * mulOther
2972 + dataCopy[offset] * mul
2976 - dataCopy[offsetPrev+1]
2977 - dataCopy[offset-3]
2978 - dataCopy[offset+5]
2979 - dataCopy[offsetNext+1]) * mulOther
2980 + dataCopy[offset+1] * mul
2984 - dataCopy[offsetPrev+2]
2985 - dataCopy[offset-2]
2986 - dataCopy[offset+6]
2987 - dataCopy[offsetNext+2]) * mulOther
2988 + dataCopy[offset+2] * mul
2995 if (r > 255 ) r = 255;
2996 if (g > 255 ) g = 255;
2997 if (b > 255 ) b = 255;
3010 checkSupport : function() {
3011 return Pixastic.Client.hasCanvasImageData();
3015 * Pixastic Lib - Solarize filter - v0.1.0
3016 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
3017 * License: [http://www.pixastic.com/lib/license.txt]
3020 Pixastic.Actions.solarize = {
3022 process : function(params) {
3023 var useAverage = !!(params.options.average && params.options.average != "false");
3025 if (Pixastic.Client.hasCanvasImageData()) {
3026 var data = Pixastic.prepareData(params);
3027 var rect = params.options.rect;
3029 var h = rect.height;
3033 var offsetY = (y-1)*w4;
3036 var offset = offsetY + (x-1)*4;
3038 var r = data[offset];
3039 var g = data[offset+1];
3040 var b = data[offset+2];
3042 if (r > 127) r = 255 - r;
3043 if (g > 127) g = 255 - g;
3044 if (b > 127) b = 255 - b;
3055 checkSupport : function() {
3056 return (Pixastic.Client.hasCanvasImageData());
3059 * Pixastic Lib - USM - v0.1.0
3060 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
3061 * License: [http://www.pixastic.com/lib/license.txt]
3065 Pixastic.Actions.unsharpmask = {
3066 process : function(params) {
3068 var amount = (parseFloat(params.options.amount)||0);
3069 var blurAmount = parseFloat(params.options.radius)||0;
3070 var threshold = parseFloat(params.options.threshold)||0;
3072 amount = Math.min(500,Math.max(0,amount)) / 2;
3073 blurAmount = Math.min(5,Math.max(0,blurAmount)) / 10;
3074 threshold = Math.min(255,Math.max(0,threshold));
3077 var thresholdNeg = -threshold;
3082 if (Pixastic.Client.hasCanvasImageData()) {
3083 var rect = params.options.rect;
3085 var blurCanvas = document.createElement("canvas");
3086 blurCanvas.width = params.width;
3087 blurCanvas.height = params.height;
3088 var blurCtx = blurCanvas.getContext("2d");
3089 blurCtx.drawImage(params.canvas,0,0);
3092 var smallWidth = Math.round(params.width / scale);
3093 var smallHeight = Math.round(params.height / scale);
3095 var copy = document.createElement("canvas");
3096 copy.width = smallWidth;
3097 copy.height = smallHeight;
3099 var steps = Math.round(blurAmount * 20);
3101 var copyCtx = copy.getContext("2d");
3102 for (var i=0;i<steps;i++) {
3103 var scaledWidth = Math.max(1,Math.round(smallWidth - i));
3104 var scaledHeight = Math.max(1,Math.round(smallHeight - i));
3106 copyCtx.clearRect(0,0,smallWidth,smallHeight);
3110 0,0,params.width,params.height,
3111 0,0,scaledWidth,scaledHeight
3114 blurCtx.clearRect(0,0,params.width,params.height);
3118 0,0,scaledWidth,scaledHeight,
3119 0,0,params.width,params.height
3123 var data = Pixastic.prepareData(params);
3124 var blurData = Pixastic.prepareData({canvas:blurCanvas,options:params.options});
3126 var h = rect.height;
3130 var offsetY = (y-1)*w4;
3133 var offset = offsetY + (x*4-4);
3135 var difR = data[offset] - blurData[offset];
3136 if (difR > threshold || difR < thresholdNeg) {
3137 var blurR = blurData[offset];
3138 blurR = amount * difR + blurR;
3139 data[offset] = blurR > 255 ? 255 : (blurR < 0 ? 0 : blurR);
3142 var difG = data[offset+1] - blurData[offset+1];
3143 if (difG > threshold || difG < thresholdNeg) {
3144 var blurG = blurData[offset+1];
3145 blurG = amount * difG + blurG;
3146 data[offset+1] = blurG > 255 ? 255 : (blurG < 0 ? 0 : blurG);
3149 var difB = data[offset+2] - blurData[offset+2];
3150 if (difB > threshold || difB < thresholdNeg) {
3151 var blurB = blurData[offset+2];
3152 blurB = amount * difB + blurB;
3153 data[offset+2] = blurB > 255 ? 255 : (blurB < 0 ? 0 : blurB);
3162 checkSupport : function() {
3163 return Pixastic.Client.hasCanvasImageData();