1 2(function ($) { 3 var handleFiles, ProgressBar, FileList, FileListInline; 4 5 $.fileTypeIcon = function (fileId, file) { 6 if(file.type.substring(0,6) == 'image/') { 7 return $('<img src="tiki-download_file.php?fileId=' + fileId + '&display&height=24" height="24">'); 8 } else if(file.type == 'application/pdf') { 9 return $('<img height="16" width="16" title="application/pdf" alt="application/pdf" src="img/icons/mime/pdf.png">'); 10 } else if(file.type.indexOf("sheet") != -1) { 11 return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/xls.png">'); 12 } else if(file.type.indexOf("zip") != -1) { 13 return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/zip.png">'); 14 } else if (file.type.substring(0,6) == 'video/') { 15 return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/flv.png">'); 16 } else if (file.type.indexOf("word") != -1) { 17 return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/doc.png">'); 18 } else { 19 return $('<img height="16" width="16" title="'+ file.type +'" alt="'+ file.type +'" src="img/icons/mime/default.png">'); 20 } 21 }; 22 23 ProgressBar = function (options) { 24 var bar = this; 25 this.segments = []; 26 this.updateSegment = function (number, current, total) { 27 bar.segments[number] = [current, total]; 28 bar.update(); 29 }; 30 this.update = function () { 31 var total = 0, current = 0; 32 $.each(bar.segments, function (k, item) { 33 current += item[0]; 34 total += item[1]; 35 }); 36 37 options.progress(current, total); 38 39 if (current === total) { 40 options.done(); 41 } 42 }; 43 }; 44 45 FileList = function (options) { 46 var $list = $(options.list); 47 this.clearErrors = function () { 48 $list.find('.text-danger').remove(); 49 }; 50 this.addError = function (file, message) { 51 var $li = $('<li>').appendTo($list); 52 53 $li.text(file.name); 54 $li.addClass('text-danger'); 55 $li.append(' (' + (message ? message : tr('uploading failed')) + ')'); 56 }; 57 this.addFile = function (fileId, file) { 58 var $li = $('<li>').appendTo($list); 59 60 $li 61 .text(file.name) 62 .prepend($.fileTypeIcon(fileId, file)); 63 $('<input type="hidden" name="file[]">') 64 .attr('value', fileId) 65 .appendTo($li) 66 }; 67 }; 68 69 FileListInline = function (options) { 70 var $list = $(options.list), 71 $form = $(options.form), 72 $files = []; 73 this.clearErrors = function () { 74 $list.find('.text-danger').remove(); 75 }; 76 this.addError = function (file) { 77 var $li = $('<li>').appendTo($form); 78 79 $li.text(file.name); 80 $li.addClass('text-danger'); 81 $li.append(' (' + tr('uploading failed') + ')'); 82 }; 83 this.success = function(data){ 84 $form.trigger('submit', [{files: $files}]); 85 }; 86 this.addFile = function (fileId, file) { 87 file.fileId = fileId; 88 $files.push(file); 89 90 var action = $form.attr('data-action'); 91 $.ajax(action, { 92 type: 'POST', 93 dataType: 'json', 94 data: { 95 files: [fileId] 96 }, 97 success: this.success 98 }); 99 }; 100 }; 101 102 handleFiles = function (input) { 103 104 var files = input.files, 105 accept = input.accept, 106 galleryId = input.galleryId, 107 image_max_size_x = input.image_max_size_x, 108 image_max_size_y = input.image_max_size_y, 109 progressBar = input.progress, 110 fileList = input.list; 111 112 var uploadUrl = $.service('file', 'upload'); 113 114 var restoreExif = function(sourceImageData, newImageData){ 115 if (!sourceImageData.startsWith('data:image/jpeg;base64,')){ 116 return newImageData; 117 } 118 var sourceImageSegments = MinifyJpeg.slice2Segments(MinifyJpeg.decode64(sourceImageData.replace("data:image/jpeg;base64,", ""))); 119 var exifInfo = MinifyJpeg.getExif(sourceImageSegments); 120 var newImageBinArray = MinifyJpeg.insertExif(newImageData, exifInfo); 121 return "data:image/jpeg;base64," + MinifyJpeg.encode64(newImageBinArray); 122 }; 123 124 $.each(files, function (k, file) { 125 var reader = new FileReader(); 126 127 progressBar.updateSegment(k, 0, file.size); 128 window.lastFile = file; 129 130 $(window).queue('process-upload', function () { 131 reader.onloadend = function (e) { 132 var xhr, provider, sendData, data, valid = true; 133 134 xhr = jQuery.ajaxSettings.xhr(); 135 if (xhr.upload) { 136 xhr.upload.addEventListener('progress', function (e) { 137 if (e.lengthComputable) { 138 progressBar.updateSegment(k, e.loaded, e.total); 139 } 140 }, false); 141 } 142 provider = function () { 143 return xhr; 144 }; 145 146 sendData = { 147 148 type: 'POST', 149 url: uploadUrl, 150 xhr: provider, 151 dataType: 'json', 152 global: false, // prevent ajaxError in tiki-jquery.js from closing the dialogs, leading to lost edits 153 success: function (data) { 154 fileList.addFile(data.fileId, file); 155 }, 156 error: function (jqXHR, textStatus, errorThrown) { 157 progressBar.updateSegment(k, 0, 0); 158 fileList.addError(file, errorThrown); 159 }, 160 complete: function () { 161 $(window).dequeue('process-upload'); 162 } 163 }; 164 165 if (window.FormData) { 166 sendData.processData = false;
167 sendData.contentType = false; 168 sendData.cache = false; 169 170 sendData.data = new FormData; 171 sendData.data.append('galleryId', galleryId); 172 sendData.data.append('image_max_size_x', image_max_size_x); 173 sendData.data.append('image_max_size_y', image_max_size_y); 174 sendData.data.append('name',file.name); 175 176 var waiting=false; 177 178 //checking if image is uploaded to call resize function and resizing options are set by tracker field creator 179 if(file.type.substring(0,6) == 'image/' && (image_max_size_x!='' || image_max_size_y!='')) { 180 waiting=true; 181 var imageData; 182 183 var picFile = e.target; 184 imageData = picFile.result; 185 186 // imageData=resizeFile(e,imageData,parseInt(image_max_size_x),parseInt(image_max_size_y)); 187 var img = new Image(); 188 var blobImage=null; 189 img.src=imageData; 190 img.onload = function(){ 191 var width = parseInt(image_max_size_x); 192 var height = parseInt(image_max_size_y); 193 var image_x = parseInt(image_max_size_x); 194 var image_y = parseInt(image_max_size_y); 195 var ratio; 196 if (img.width > image_x || img.height > image_y) { 197 198 if (img.width > image_x) { 199 width = image_x; 200 ratio = image_x / img.width; 201 height = Math.round(img.height * ratio); 202 } 203 204 if (height >image_y) { 205 height =image_y; 206 ratio = image_y / img.height; 207 width = Math.round(img.width * ratio); 208 } 209 } 210 else 211 { 212 width=img.width; 213 height=img.height; 214 } 215 var canvas = $("<canvas/>").get(0); 216 canvas.width = width; 217 canvas.height = height; 218 var context = canvas.getContext('2d'); 219 context.drawImage(img, 0, 0, width, height); 220 var resizedImage = restoreExif(imageData, canvas.toDataURL('image/jpeg')); 221 blobImage = dataURItoBlob(resizedImage); 222 sendData.data.append('data',blobImage,file.name); 223 $.ajax(sendData); 224 } 225 226 } 227 else 228 sendData.data.append('data', file); 229 } else { 230 data = e.target.result; 231 sendData.data = { 232 name: file.name, 233 size: file.size, 234 type: file.type, 235 data: data.substr(data.indexOf('base64') + 7), 236 galleryId: galleryId, 237 image_max_size_x:image_max_size_x, 238 image_max_size_y:image_max_size_y 239 }; 240 } 241 242 if (accept) { 243 valid = file.type.match(new RegExp( ".?(" + accept.replace('*', '.*') + ")$", "i")); 244 } 245 246 if (valid && !waiting) { 247 $.ajax(sendData); 248 } else if(!valid) { 249 sendData.error(null); 250 } 251 }; 252 reader.readAsDataURL(file); 253 }); 254 }); 255 $(window).dequeue('process-upload'); 256 }; 257 258 $(document).on('submit', 'form.file-uploader', function (e) { 259 e.preventDefault(); 260 }); 261 262 function doUpload($form, files) { 263 var progress, list; 264 265 progress = new ProgressBar({ 266 progress: function (current, total) { 267 var percentage = Math.round(current / total * 100); 268 269 $form.find('.progress').removeClass('hidden'); 270 $form.find('.progress-bar') 271 .attr('aria-valuenow', percentage) 272 .width(percentage + '%'); 273 $form.find('.progress-bar .sr-only .count') 274 .text(percentage); 275 }, 276 done: function () { 277 $form.find('.progress').addClass('hidden'); 278 $form.find('.progress-bar') 279 .attr('aria-valuenow', 0) 280 .width('0%'); 281 $form.find('.progress-bar .sr-only .count') 282 .text('0%'); 283 } 284 }); 285 286 if($form.is(".inline")){ 287 list = new FileListInline({ 288 list: $form.parent().find('.file-uploader-result ul')[0], 289 form: $form 290 }); 291 } else { 292 list = new FileList({ 293 list: $form.parent().find('.file-uploader-result ul')[0] 294 }); 295 } 296 297 list.clearErrors(); 298 299 handleFiles({ 300 accept: $form.find(':file').attr('accept'), 301 galleryId: $form.data('gallery-id'), 302 image_max_size_x:$form.data('image_max_size_x'), 303 image_max_size_y:$form.data('image_max_size_y'), 304 files: files, 305 progress: progress, 306 list: list 307 }); 308 } 309
310 $(document).on('change', '.file-uploader input[type=file]', function () { 311 312 var $clone, $form = $(this).closest('.file-uploader'), progress, list; 313 if (this.files) { 314 315 doUpload($form, this.files); 316 317 $(this).val(''); 318 $clone = $(this).clone(true); 319 $(this).replaceWith($clone); 320 } 321 }); 322 323 if (window.FileReader) { 324 $(document).ready(function () { 325 $('.drop-message').show(); 326 }); 327 $(document).on('dragenter', '.file-uploader', function (e) { 328 e.preventDefault(); 329 e.stopPropagation(); 330 $(this).css('border', '2px dashed gray'); 331 return false; 332 }); 333 $(document).on('dragexit', '.file-uploader', function (e) { 334 e.preventDefault(); 335 e.stopPropagation(); 336 $(this).css('border', ''); 337 return false; 338 }); 339 $(document).on('dragover', '.file-uploader', function (e) { 340 e.preventDefault(); 341 e.stopPropagation(); 342 return false; 343 }); 344 $(document).on('drop', '.file-uploader', function (e) { 345 var $form = $(this); 346 347 e.preventDefault(); 348 e.stopPropagation(); 349 $(this).css('border', ''); 350 351 var dataTransfer = e.dataTransfer; 352 if (! dataTransfer) { 353 dataTransfer = e.originalEvent.dataTransfer; 354 } 355 356 if (dataTransfer && dataTransfer.files) { 357 doUpload($form, dataTransfer.files); 358 } 359 return false; 360 }); 361 } 362 363 function browserRemoveFile(link) 364 { 365 var list = $(link).closest('ul'); 366 $(link).closest('li').remove(); 367 368 list.closest('.file-browser').trigger('selection-update'); 369 } 370 371 function browserAddFile(link) 372 { 373 var content = $(link).closest('.media-body').clone(true), 374 icon = $(link).closest('.media, .panel').find('.media-object, .panel-body a').children('img').clone(true).width('16px'), 375 nav = $(link).closest('.file-browser').find('.selection ul'), 376 item = $('<li>'), 377 a = $('<a>').text($(link).text()), 378 id = $(link).data('object'), 379 limit = nav.closest('form').data('limit'), 380 current = nav.find('input[type=hidden]').filter(function () { 381 return parseInt($(this).val(), 10) === id; 382 }); 383 384 if (current.length > 0) { 385 // Already in the list 386 browserRemoveFile(current[0]); 387 return; 388 } 389 390 if (limit === 1) { 391 nav.empty(); 392 } else if (limit && nav.children('li').length >= limit) { 393 alert(nav.closest('form').data('limit-reached-message')); 394 return; 395 } 396 397 a 398 .prepend(' ') 399 .prepend(icon); 400 item.append(a); 401 nav.append(item); 402 403 item.append($('<input type="hidden" name="file[]">') 404 .attr('value', id)); 405 406 nav.closest('.file-browser').trigger('selection-update'); 407 } 408 409 $(document).on('selection-update', '.file-browser', function (e) { 410 var selection = $('.selection input[type=hidden]', this).map(function () { 411 return parseInt($(this).val(), 10); 412 }); 413 414 $('.gallery-list .media-heading a, .gallery-list .panel-body a', this).each(function () { 415 var id = $(this).data('object'); 416 $(this).closest('.media').toggleClass('bg-info', -1 !== $.inArray(id, selection)); 417 $(this).closest('.panel').toggleClass('panel-info', -1 !== $.inArray(id, selection)); 418 }); 419 $('.selection', this).toggleClass('hidden', selection.length === 0); 420 }); 421 422 $(document).on('click', '.file-browser .gallery-list .pagination a', function (e) { 423 e.preventDefault(); 424 $(this).closest('.modal').animate({ scrollTop: 0 }, 'slow'); 425 $(this).closest('.gallery-list') 426 .tikiModal(tr('Loading...')) 427 .load($(this).attr('href'), function () { 428 $(this).tikiModal(''); 429 $(this).closest('.file-browser').trigger('selection-update'); 430 }); 431 }); 432 433 $(document).on('click', '.file-browser .gallery-list .media-heading a, .file-browser .gallery-list .panel-body a', function (e) { 434 e.preventDefault(); 435 e.stopPropagation(); 436 browserAddFile(this); 437 }); 438 $(document).on('click', '.file-browser .gallery-list .media, .file-browser .gallery-list .panel', function (e) { 439 e.preventDefault(); 440 $('.media-heading a, .panel-body a', this).click(); 441 }); 442 443 $(document).on('click', '.file-browser .selection a', function (e) { 444 e.preventDefault(); 445 browserRemoveFile(this); 446 }); 447 448 $(document).on('submit', '.file-browser .form-inline', function (e) { 449 e.preventDefault(); 450 $(this).closest('.file-browser').find('.gallery-list') 451 .tikiModal(tr('Loading...')) 452 .load($(this).attr('action'), $(this).serialize(), function () { 453 $(this).tikiModal(''); 454 $(this).closest('.file-browser').trigger('selection-update'); 455 }); 456 }); 457 458 $(document).on('click', '.file-browser .submit .upload-files', function (e) { 459 var $list = $(this).closest('.file-browser').find('.selection ul'), 460 handler = $.clickModal({ 461 success: function (data) { 462 $.each(data.files, function (k, file) { 463 $('<li>') 464 .append($('<a href="#">') 465 .data('object', file.fileId)
466 .data('type', 'file') 467 .text(file.label)) 468 .append($('<input type="hidden" name="file[]">') 469 .attr('value', file.fileId)) 470 .appendTo($list); 471 472 $list.closest('.file-browser').trigger('selection-update'); 473 }); 474 $.closeModal(); 475 } 476 }); 477 478 handler.apply(this, arguments); 479 }); 480 481 // File selector component 482 $(document).on('click', '.file-selector a', function () { 483 if (! $(this).data('initial-href')) { 484 $(this).data('initial-href', $(this).attr('href')); 485 } 486 487 // Before the dialog handler triggers, replace the href with one including current files 488 $(this).attr('href', $(this).data('initial-href') + '&file=' + $(this).parent().children('input').val()); 489 }); 490 $(document).on('click', '.file-selector a', $.clickModal({ 491 size: 'modal-lg', 492 success: function (data) { 493 var files = []; 494 $.each(data.files, function (k, f) { 495 files.push(f.fileId); 496 }); 497 $(this).parent().children('input').val(files.join(',')); 498 $(this).text($(this).text().replace(/\d+/, files.length)); 499 $.closeModal(); 500 } 501 })); 502})(jQuery); 503 504 505 function resizeFile(e,imageData,image_x,image_y) { 506 507 //var picReader = new FileReader(); 508 //picReader.readAsDataURL(file); 509 return blobImage; 510} 511 512function dataURItoBlob(dataURI) { 513 514 515 // convert base64/URLEncoded data component to raw binary data held in a string 516 var byteString; 517 if (dataURI.split(',')[0].indexOf('base64') >= 0) 518 byteString = atob(dataURI.split(',')[1]); 519 else 520 byteString = unescape(dataURI.split(',')[1]); 521 522 // separate out the mime component 523 var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; 524 525 // write the bytes of the string to a typed array 526 var ia = new Uint8Array(byteString.length); 527 for (var i = 0; i < byteString.length; i++) { 528 ia[i] = byteString.charCodeAt(i); 529 } 530 531 return new Blob([ia],{ type:'image/jpeg' }); 532} 533 534/* To minify a jpeg image without loosing EXIF. 535 * TESTED(24/01/2013): FireFox, GoogleChrome, IE10, Opera 536 * Copyright (c) 2013 hMatoba 537 * Released under the MIT license : https://github.com/hMatoba/MinifyJpegAsync/blob/master/LICENSE.txt 538 * 539 * To minify jpeg image: 540 * minified = MinifyJpeg.minify(image, length); 541 * xhr.send(minified.buffer); 542 * enc = "data:image/jpeg;base64," + MinifyJpeg.encode64(minified); 543 * html = '<img src="' + enc + '">'; 544 * MinifyJpeg.minify() - return Uint8Array 545 * image - image base64encoded, it can be obtained "FileReader().readAsDataURL(f)" 546 * length - the long side length of the rectangle 547 * MinifyJpeg.encode64() - convert array to base64encoded string 548 */ 549var MinifyJpeg = (function() 550{ 551/* 552 if (typeof JpegImage == "undefined") 553 { 554 throw new ReferenceError("Load jpg.js!"); 555 } 556*/ 557 var that = {}; 558 559 that.KEY_STR = "ABCDEFGHIJKLMNOP" + 560 "QRSTUVWXYZabcdef" + 561 "ghijklmnopqrstuv" + 562 "wxyz0123456789+/" + 563 "="; 564 565 that.SOF = [192, 193, 194, 195, 197, 198, 199, 201, 202, 203, 205, 206, 207]; 566 567 that.minify = function(image, new_size) 568 { 569 if (image instanceof ArrayBuffer) 570 { 571 if (image[0] == 255 && image[1] == 216) 572 { 573 var rawImage = []; 574 for (var i=0; i<image.byteLength; i++) 575 { 576 rawImage[i] = image[i]; 577 } 578 } 579 else 580 { 581 throw "MinifyJpeg.minify got a not JPEG data"; 582 } 583 } 584 else if (typeof(image) == "string") 585 { 586 if (!image.match("data:image/jpeg;base64,")) 587 { 588 throw "MinifyJpeg.minify got a not JPEG data"; 589 } 590 else 591 { 592 var rawImage = that.decode64(image.replace("data:image/jpeg;base64,", "")); 593 } 594 } 595 else 596 { 597 throw "First argument must be 'DataURL string' or ArrayBuffer."; 598 } 599 600 var segments = that.slice2Segments(rawImage); 601 var NEW_SIZE = parseInt(new_size); 602 var size = that.imageSizeFromSegments(segments); 603 var chouhen = (size[0] >= size[1]) ? size[0] : size[1]; 604 if (chouhen < NEW_SIZE) 605 { 606 return new Uint8Array(rawImage); 607 } 608 609 var exif = that.getExif(segments); 610 var resized = that.resizeImage(rawImage, segments, NEW_SIZE); 611 612 if (exif.length) 613 { 614 var newImage = that.insertExif(resized, exif); 615 } 616 else 617 { 618 var newImage = new Uint8Array(that.decode64(resized.replace("data:image/jpeg;base64,", ""))); 619 } 620 621 return newImage; 622 }; 623 624 that.getImageSize = function(imageArray) 625 { 626 var segments = that.slice2Segments(imageArray); 627 return that.imageSizeFromSegments(segments); 628 }; 629 630 that.slice2Segments = function(rawImageArray) 631 { 632 var head = 0, 633 segments = []; 634 635 while (1) 636 { 637 if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218) 638 { 639 break; 640 } 641 if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216) 642 { 643 head += 2; 644 } 645 else 646 { 647 var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3], 648 endPoint = head + length + 2, 649 seg = rawImageArray.slice(head, endPoint); 650 segments.push(seg); 651 head = endPoint; 652 } 653 if (head > rawImageArray.length) 654 { 655 break; 656 } 657 } 658 659 return segments; 660 }; 661 662 that.imageSizeFromSegments = function(segments) 663 { 664 for (var x=0; x<segments.length; x++) 665 { 666 var seg = segments[x]; 667 if (that.SOF.indexOf(seg[1]) >= 0) 668 { 669 var height = seg[5] * 256 + seg[6], 670 width = seg[7] * 256 + seg[8]; 671 break; 672 } 673 } 674 return [width, height]; 675 }; 676 677 that.encode64 = function(input) 678 { 679 var output = "", 680 chr1, chr2, chr3 = "", 681 enc1, enc2, enc3, enc4 = "", 682 i = 0; 683 684 do {
685 chr1 = input[i++]; 686 chr2 = input[i++]; 687 chr3 = input[i++]; 688 689 enc1 = chr1 >> 2; 690 enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 691 enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 692 enc4 = chr3 & 63; 693 694 if (isNaN(chr2)) { 695 enc3 = enc4 = 64; 696 } else if (isNaN(chr3)) { 697 enc4 = 64; 698 } 699 700 output += that.KEY_STR.charAt(enc1) + 701 that.KEY_STR.charAt(enc2) + 702 that.KEY_STR.charAt(enc3) + 703 that.KEY_STR.charAt(enc4); 704 chr1 = chr2 = chr3 = ""; 705 enc1 = enc2 = enc3 = enc4 = ""; 706 } while (i < input.length); 707 return output; 708 }; 709 710 that.decode64 = function(input) { 711 var output = "", 712 chr1, chr2, chr3 = "", 713 enc1, enc2, enc3, enc4 = "", 714 i = 0, 715 buf = []; 716 717 // remove all characters that are not A-Z, a-z, 0-9, +, /, or = 718 var base64test = /[^A-Za-z0-9\+\/\=]/g; 719 if (base64test.exec(input)) { 720 alert("There were invalid base64 characters in the input text.\n" + 721 "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" + 722 "Expect errors in decoding."); 723 } 724 input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); 725 726 do { 727 enc1 = that.KEY_STR.indexOf(input.charAt(i++)); 728 enc2 = that.KEY_STR.indexOf(input.charAt(i++)); 729 enc3 = that.KEY_STR.indexOf(input.charAt(i++)); 730 enc4 = that.KEY_STR.indexOf(input.charAt(i++)); 731 732 chr1 = (enc1 << 2) | (enc2 >> 4); 733 chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); 734 chr3 = ((enc3 & 3) << 6) | enc4; 735 736 buf.push(chr1); 737 738 if (enc3 != 64) { 739 buf.push(chr2); 740 } 741 if (enc4 != 64) { 742 buf.push(chr3); 743 } 744 745 chr1 = chr2 = chr3 = ""; 746 enc1 = enc2 = enc3 = enc4 = ""; 747 748 } while (i < input.length); 749 750 return buf; 751 }; 752 753 that.resizeImage = function(rawImage, segments, NEW_SIZE) 754 { 755 var size = that.imageSizeFromSegments(segments), 756 width = size[0], 757 height = size[1], 758 chouhen = (width>=height) ? width : height, 759 newSize = NEW_SIZE, 760 resizing = 1, 761 scale = parseFloat(newSize) / chouhen, 762 newWidth = parseInt(parseFloat(newSize) / chouhen * width), 763 newHeight = parseInt(parseFloat(newSize) / chouhen * height); 764 765 if (resizing == 1) // bilinear 766 { 767 var canvas = document.createElement('canvas'); 768 canvas.width = width; 769 canvas.height = height; 770 771 var jpe = new JpegImage(), 772 ctx = canvas.getContext("2d"), 773 srcImg = ctx.getImageData(0, 0, width, height); 774 jpe.parse(new Uint8Array(rawImage)); 775 jpe.copyToImageData(srcImg); 776 777 var newCanvas = document.createElement('canvas'); 778 newCanvas.width = newWidth; 779 newCanvas.height = newHeight; 780 var newCtx = newCanvas.getContext("2d"); 781 var destImg = newCtx.createImageData(newWidth, newHeight); 782 that.bilinear(srcImg, destImg, scale); 783 784 newCtx.putImageData(destImg, 0, 0); 785 var resizedImage = newCanvas.toDataURL("image/jpeg"); 786 } 787 else // nearest neighbor? 788 { 789 var canvas = document.createElement('canvas'); 790 canvas.width = newWidth; 791 canvas.height = newHeight; 792 793 var jpe = new JpegImage(); 794 ctx = canvas.getContext("2d"); 795 d = ctx.getImageData(0, 0, newWidth, newHeight); 796 jpe.parse(new Uint8Array(rawImage)); 797 jpe.copyToImageData(d); 798 ctx.putImageData(d, 0, 0); 799 800 var resizedImage = canvas.toDataURL("image/jpeg"); 801 } 802 803 return resizedImage; 804 }; 805 806 that.getExif = function(segments) 807 { 808 var seg; 809 for (var x=0; x<segments.length; x++) 810 { 811 seg = segments[x]; 812 if (seg[0] == 255 & seg[1] == 225) //(ff e1) 813 { 814 return seg; 815 } 816 } 817 return []; 818 } 819 820 that.insertExif = function(imageStr, exifArray) 821 { 822 var buf = that.decode64(imageStr.replace("data:image/jpeg;base64,", "")), 823 separatePoint = buf.indexOf(255,3), 824 mae = buf.slice(0, separatePoint), 825 ato = buf.slice(separatePoint), 826 array = mae.concat(exifArray, ato); 827 828 aBuffer = new Uint8Array(array); 829 830 return aBuffer; 831 }; 832 833 // compute vector index from matrix one 834 that.ivect = function (ix, iy, w) { 835 // byte array, r,g,b,a 836 return((ix + w * iy) * 4); 837 }; 838 839 that.bilinear = function (srcImg, destImg, scale) { 840 // c.f.: wikipedia english article on bilinear interpolation 841 //log.debug("in bilinear"); 842 // taking the unit square 843 function inner(f00, f10, f01, f11, x, y) { 844 var un_x = 1.0 - x; var un_y = 1.0 - y; 845 return (f00 * un_x * un_y + f10 * x * un_y + f01 * un_x * y + f11 * x * y); 846 } 847 var srcWidth = srcImg.width;
848 var srcHeight = srcImg.height; 849 var srcData = srcImg.data; 850 var dstData = destImg.data; 851 var i, j; 852 var iyv, iy0, iy1, ixv, ix0, ix1; 853 var idxD, idxS00, idxS10, idxS01, idxS11; 854 var dx, dy; 855 var r, g, b, a; 856 for (i = 0; i < destImg.height; ++i) { 857 iyv = (i + 0.5) / scale - 0.5; 858 iy0 = Math.floor(iyv); 859 iy1 = ( Math.ceil(iyv) > (srcHeight-1) ? (srcHeight-1) : Math.ceil(iyv) ); 860 for (j = 0; j < destImg.width; ++j) { 861 ixv = (j + 0.5) / scale - 0.5; 862 ix0 = Math.floor(ixv); 863 ix1 = ( Math.ceil(ixv) > (srcWidth-1) ? (srcWidth-1) : Math.ceil(ixv) ); 864 idxD = that.ivect(j, i, destImg.width); 865 idxS00 = that.ivect(ix0, iy0, srcWidth); 866 idxS10 = that.ivect(ix1, iy0, srcWidth); 867 idxS01 = that.ivect(ix0, iy1, srcWidth); 868 idxS11 = that.ivect(ix1, iy1, srcWidth); 869 // log.debug(sprintf("bilinear: idx: D: %d, S00: %d, S10: %d, S01: %d, S11: %d", idxD, idxS00, idxS10, idxS01, idxS11)); 870 dx = ixv - ix0; dy = iyv - iy0; 871 872 //r 873 dstData[idxD] = inner(srcData[idxS00], srcData[idxS10], 874 srcData[idxS01], srcData[idxS11], dx, dy); 875 876 //g 877 dstData[idxD+1] = inner(srcData[idxS00+1], srcData[idxS10+1], 878 srcData[idxS01+1], srcData[idxS11+1], dx, dy); 879 880 //b 881 dstData[idxD+2] = inner(srcData[idxS00+2], srcData[idxS10+2], 882 srcData[idxS01+2], srcData[idxS11+2], dx, dy); 883 884 //a 885 dstData[idxD+3] = inner(srcData[idxS00+3], srcData[idxS10+3], 886 srcData[idxS01+3], srcData[idxS11+3], dx, dy); 887 888 // log.debug(sprintf("pixel: j:%d, i:%d; r:%d, g:%d, b:%d", j, i, r, g, b)); 889 } 890 } 891 }; 892 return that; 893})();
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.