1/* global POP, MAIN, SIFT, LAYER, IMAGE, EVENTS, HELPER, EDIT, GUI, EL */ 2/* global WIDTH, HEIGHT, COLOR, canvas_active */ 3 4var TOOLS = new TOOLS_CLASS(); 5 6/** 7 * manages various tools 8 * 9 * @author toolpic.com 10 */ 11function TOOLS_CLASS() { 12 13 //sprites 14 this.tools_sprites = function () { 15 POP.add({name: "param1", title: "Gap:", value: "50", values: ["0", "10", "50", "100"]}); 16 POP.add({name: "param2", title: "Width:", value: WIDTH}); 17 POP.show('Sprites', function (response) { 18 EDIT.save_state(); 19 var param1 = parseInt(response.param1); 20 var sprite_width = parseInt(response.param2); 21 TOOLS.generate_sprites(param1, sprite_width); 22 }); 23 }; 24 25 //show keypoints 26 this.tools_keypoints = function () { 27 SIFT.generate_keypoints(canvas_active(true), true); 28 }; 29 30 //create panorama 31 this.tools_panorama = function () { 32 SIFT.panorama(); 33 }; 34 35 //extract alpha channel 36 this.tools_color2alpha = function () { 37 POP.add({name: "param1", title: "Color:", value: COLOR, type: 'color'}); 38 POP.show( 39 'Color to alpha', 40 function (user_response) {
41 EDIT.save_state(); 42 var param1 = user_response.param1; 43 TOOLS.convert_color_to_alpha(canvas_active(), WIDTH, HEIGHT, param1); 44 GUI.zoom(); 45 }, 46 function (user_response, canvas_preview, w, h) { 47 var param1 = user_response.param1; 48 TOOLS.convert_color_to_alpha(canvas_preview, w, h, param1); 49 } 50 ); 51 }; 52 53 //expands colors 54 this.tools_color_zoom = function () { 55 POP.add({name: "param1", title: "Zoom:", value: "2", range: [2, 20], }); 56 POP.add({name: "param2", title: "Center:", value: "128", range: [0, 255]}); 57 POP.show( 58 'Color Zoom', 59 function (user_response) { 60 EDIT.save_state(); 61 var param1 = parseInt(user_response.param1); 62 var param2 = parseInt(user_response.param2); 63 64 TOOLS.color_zoom(canvas_active(), WIDTH, HEIGHT, param1, param2); 65 GUI.zoom(); 66 }, 67 function (user_response, canvas_preview, w, h) { 68 var param1 = parseInt(user_response.param1); 69 var param2 = parseInt(user_response.param2); 70 71 TOOLS.color_zoom(canvas_preview, w, h, param1, param2); 72 } 73 ); 74 }; 75 76 //recover alpha channel values 77 this.tools_restore_alpha = function () { 78 POP.add({name: "param", title: "Level:", value: "128", range: [0, 255]}); 79 POP.show( 80 'Recover alpha', 81 function (user_response) {
82 EDIT.save_state(); 83 var param = parseInt(user_response.param); 84 85 TOOLS.recover_alpha(canvas_active(), WIDTH, HEIGHT, param); 86 GUI.zoom(); 87 }, 88 function (user_response, canvas_preview, w, h) { 89 var param = parseInt(user_response.param); 90 91 TOOLS.recover_alpha(canvas_preview, w, h, param); 92 } 93 ); 94 }; 95 96 //adds borders 97 this.tools_borders = function () { 98 POP.add({name: "color", title: "Color:", value: COLOR, type: 'color'}); 99 POP.add({name: "shadow", title: "Shadow:", values: ["No", "Yes"]}); 100 POP.add({name: "size", title: "Size:", value: "5", range: [1, 100]}); 101 POP.show( 102 'Borders', 103 function (user_response) { 104 EDIT.save_state(); 105 var color = user_response.color; 106 var size = Math.round(WIDTH / 100 * user_response.size); 107 var shadow = false; 108 if(user_response.shadow == 'Yes') 109 shadow = true; 110 111 TOOLS.add_borders(canvas_active(), WIDTH, HEIGHT, color, size, shadow); 112 GUI.zoom(); 113 }, 114 function (user_response, canvas_preview, w, h) { 115 var color = user_response.color; 116 var size = Math.round(w / 100 * user_response.size); 117 var shadow = false; 118 if(user_response.shadow == 'Yes') 119 shadow = true; 120 121 TOOLS.add_borders(canvas_preview, w, h, color, size, shadow); 122 } 123 ); 124 }; 125 126 this.generate_sprites = function (gap, sprite_width) { 127 if (LAYER.layers.length == 1) 128 return false; 129 EDIT.save_state(); 130 LAYER.layer_add(); 131 var xx = 0; 132 var yy = 0; 133 var max_height = 0; 134 var tmp = document.createElement("canvas"); 135 tmp.setAttribute('id', "tmp_canvas"); 136 tmp.width = sprite_width; 137 tmp.height = HEIGHT; 138 var W = sprite_width; 139 var H = HEIGHT; 140 141 //prepare width 142 WIDTH = sprite_width; 143 LAYER.set_canvas_size(); 144 145 for(var i = LAYER.layers.length-1; i >=0; i--){ 146 if (i == LAYER.layer_active) 147 continue; //end 148 if (LAYER.layers[i].visible == false) 149 continue; 150 151 tmp.getContext("2d").clearRect(0, 0, W, H); 152 tmp.getContext("2d").drawImage(document.getElementById(LAYER.layers[i].name), 0, 0); 153 154 var trim_details = IMAGE.trim_info(tmp, false); //trim 155 if (WIDTH == trim_details.left) 156 continue; //empty layer 157 var width = W - trim_details.left - trim_details.right; 158 var height = H - trim_details.top - trim_details.bottom; 159 160 if (xx + width > sprite_width) { 161 xx = 0; 162 yy += max_height; 163 max_height = 0; 164 } 165 if (yy % gap > 0 && gap > 0) 166 yy = yy - yy % gap + gap; 167 if (yy + height > HEIGHT) { 168 EVENTS.autosize = false; 169 HEIGHT = yy + height; 170 LAYER.set_canvas_size(); 171 } 172 173 canvas_active().drawImage(tmp, trim_details.left, trim_details.top, width, height, xx, yy, width, height); 174 xx += width; 175 if (gap > 0) 176 xx = xx - xx % gap + gap; 177 178 if (height > max_height) 179 max_height = height; 180 if (xx > sprite_width) { 181 xx = 0; 182 yy += max_height; 183 max_height = 0; 184 } 185 } 186 187 //remove other layers 188 for(var i = LAYER.layers.length-1; i >= 0; i--) { 189 if (i == LAYER.layer_active) 190 continue; 191 LAYER.layer_remove(i, true); 192 } 193 LAYER.layer_renew(); 194 }; 195 196 this.convert_color_to_alpha = function (context, W, H, color) { 197 var img = context.getImageData(0, 0, W, H); 198 var imgData = img.data; 199 var back_color = HELPER.hex2rgb(color); 200 201 for (var i = 0; i < imgData.length; i += 4) { 202 if (imgData[i + 3] == 0) 203 continue; //transparent 204 205 //calculate difference from requested color, and change alpha 206 var diff = Math.abs(imgData[i] - back_color.r) + Math.abs(imgData[i + 1] - back_color.g) + Math.abs(imgData[i + 2] - back_color.b) / 3; 207 imgData[i + 3] = Math.round(diff); 208 209 //combining 2 layers in future will change colors, so make changes to get same colors in final image 210 //color_result = color_1 * (alpha_1 / 255) * (1 - A2 / 255) + color_2 * (alpha_2 / 255) 211 //color_2 = (color_result - color_1 * (alpha_1 / 255) * (1 - A2 / 255)) / (alpha_2 / 255) 212 imgData[i] = Math.ceil((imgData[i] - back_color.r * (1 - imgData[i + 3] / 255)) / (imgData[i + 3] / 255)); 213 imgData[i + 1] = Math.ceil((imgData[i + 1] - back_color.g * (1 - imgData[i + 3] / 255)) / (imgData[i + 3] / 255)); 214 imgData[i + 2] = Math.ceil((imgData[i + 2] - back_color.b * (1 - imgData[i + 3] / 255)) / (imgData[i + 3] / 255)); 215 } 216 context.putImageData(img, 0, 0); 217 }; 218 219 this.color_zoom = function (context, W, H, zoom, center) { 220 var img = context.getImageData(0, 0, W, H); 221 var imgData = img.data; 222 var grey; 223 for (var i = 0; i < imgData.length; i += 4) { 224 if (imgData[i + 3] == 0) 225 continue; //transparent 226 227 grey = Math.round(0.2126 * imgData[i] + 0.7152 * imgData[i + 1] + 0.0722 * imgData[i + 2]); 228 229 for (var j = 0; j < 3; j++) { 230 var k = i + j; 231 if (grey > center) 232 imgData[k] += (imgData[k] - center) * zoom; 233 else if (grey < center) 234 imgData[k] -= (center - imgData[k]) * zoom; 235 if (imgData[k] < 0) 236 imgData[k] = 0; 237 if (imgData[k] > 255) 238 imgData[k] = 255; 239 } 240 } 241 context.putImageData(img, 0, 0); 242 }; 243 244 this.recover_alpha = function (context, W, H, level) { 245 var img = context.getImageData(0, 0, W, H); 246 var imgData = img.data; 247 var tmp; 248 level = parseInt(level); 249 for (var i = 0; i < imgData.length; i += 4) { 250 tmp = imgData[i + 3] + level; 251 if (tmp > 255) 252 tmp = 255; 253 imgData[i + 3] = tmp; 254 } 255 context.putImageData(img, 0, 0); 256 }; 257 258 this.add_borders = function (context, W, H, color, size, shadow) { 259 context.save(); 260 if(shadow == true){ 261 //with shadow 262 context.beginPath(); 263 context.lineWidth = size; 264 context.strokeStyle = 'green'; 265 context.shadowColor = color; 266 context.shadowBlur = size/2; 267 context.rect(-size/2, -size/2, W+size, H+size);
268 context.stroke(); 269 context.stroke(); 270 context.stroke(); 271 context.stroke(); 272 context.stroke(); 273 } 274 else{ 275 context.strokeStyle = color; 276 context.lineWidth = size; 277 EL.rectangle(context, 0, 0, W-1, H-1, false, true); 278 } 279 context.restore(); 280 }; 281 282 this.tools_replace_color = function(){ 283 POP.add({name: "target", title: "Target:", value: COLOR, type: 'color'}); 284 POP.add({name: "repalcement", title: "Replacement:", value: '#ff0000', type: 'color'}); 285 POP.add({name: "power", title: "Power:", value: "20", range: [0, 255]}); 286 POP.add({name: "alpha", title: "Alpha:", value: "255", range: [0, 255]}); 287 POP.add({name: "mode", title: "Mode:", values: ['Advanced', 'Simple']}); 288 POP.show( 289 'Replace color', 290 function (user_response) { 291 EDIT.save_state(); 292 var target = user_response.target; 293 var repalcement = user_response.repalcement; 294 var power = user_response.power; 295 var alpha = user_response.alpha; 296 var advanced_mode = true; 297 if(user_response.mode == 'Simple') 298 advanced_mode = false; 299 300 TOOLS.replace_color_process(canvas_active(), WIDTH, HEIGHT, target, repalcement, power, alpha, advanced_mode); 301 GUI.zoom(); 302 }, 303 function (user_response, canvas_preview, w, h) { 304 var target = user_response.target; 305 var repalcement = user_response.repalcement; 306 var power = user_response.power; 307 var alpha = user_response.alpha; 308 var advanced_mode = true; 309 if(user_response.mode == 'Simple') 310 advanced_mode = false; 311 312 TOOLS.replace_color_process(canvas_preview, w, h, target, repalcement, power, alpha, advanced_mode); 313 } 314 ); 315 }; 316 317 this.replace_color_process = function(context, W, H, target, replacement, power, alpha, advanced_mode){ 318 var img = context.getImageData(0, 0, W, H); 319 var imgData = img.data; 320 var target_rgb = HELPER.hex2rgb(target); 321 var target_hsl = HELPER.rgbToHsl(target_rgb.r, target_rgb.g, target_rgb.b); 322 var target_normalized = HELPER.hslToRgb(target_hsl[0], target_hsl[1], 0.5); 323 324 var replacement_rgb = HELPER.hex2rgb(replacement); 325 var replacement_hsl = HELPER.rgbToHsl(replacement_rgb.r, replacement_rgb.g, replacement_rgb.b); 326 327 for (var i = 0; i < imgData.length; i += 4) { 328 if (imgData[i + 3] == 0) 329 continue; //transparent 330 331 if(advanced_mode == false){ 332 //simple replace 333 334 //calculate difference from requested color, and change alpha 335 var diff = (Math.abs(imgData[i] - target_rgb.r) + Math.abs(imgData[i + 1] - target_rgb.g) + Math.abs(imgData[i + 2] - target_rgb.b) ) / 3; 336 if(diff > power) 337 continue; 338 339 imgData[i] = replacement_rgb.r; 340 imgData[i + 1] = replacement_rgb.g; 341 imgData[i + 2] = replacement_rgb.b; 342 if(alpha < 255) 343 imgData[i + 3] = alpha; 344 } 345 else{ 346 //advanced replace using HSL 347 348 var hsl = HELPER.rgbToHsl(imgData[i], imgData[i+1], imgData[i+2]); 349 var normalized = HELPER.hslToRgb(hsl[0], hsl[1], 0.5); 350 var diff = (Math.abs(normalized[0] - target_normalized[0]) + Math.abs(normalized[1] - target_normalized[1]) + Math.abs(normalized[2] - target_normalized[2]) ) / 3; 351 if(diff > power) 352 continue; 353 354 //change to new color with exiting luminance 355 var replacement_normalized = HELPER.hslToRgb(replacement_hsl[0], replacement_hsl[1], hsl[2] * (replacement_hsl[2]*255) / 120); 356 357 imgData[i] = replacement_normalized[0]; 358 imgData[i + 1] = replacement_normalized[1]; 359 imgData[i + 2] = replacement_normalized[2]; 360 if(alpha < 255) 361 imgData[i + 3] = alpha; 362 } 363 } 364 context.putImageData(img, 0, 0); 365 }; 366}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.