Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  
  <input type="file" id="file" multiple><br>
  <div id="progress"></div>
</body>
</html>
 
img {
  margin-right: 10px;
}
#progress {
  font-family: courier;
  margin: 40px;
}
 
// noprotect
var width = 320;
function taskQueue(capacity) {
  var running = 0;
  var queue = [];
  function release() {
    if (queue.length) {
      var task = queue.shift();
      task(release);
    } else {
      running -= 1;
    }
  }
  return function(task) {
    if (running < capacity) {
      running += 1;
      task(release);
    } else {
      queue.push(task);
    }
  };
}
function protect(img) {
  var ratio = img.width / img.height;
  
  var maxSquare = 5000000;  // ios max canvas square
  var maxSize = 4096;  // ie max canvas dimensions
  
  var maxW = Math.floor(Math.sqrt(maxSquare * ratio));
  var maxH = Math.floor(maxSquare / Math.sqrt(maxSquare * ratio));
  if (maxW > maxSize) {
    maxW = maxSize;
    maxH = Math.round(maxW / ratio);
  }
  if (maxH > maxSize) {
    maxH = maxSize;
    maxW = Math.round(ratio * maxH);
  }
  if (img.width > maxW) {
    var canvas = document.createElement('canvas');
    canvas.width = maxW;
    canvas.height = maxH;
    canvas.getContext('2d').drawImage(img, 0, 0, maxW, maxH);
    img = canvas;
  }
  
  return img;
}
var resizeQueue = taskQueue(1); // Number of simultaneous tasks.
function resize(img, w,  h) {
  var df = $.Deferred();
  resizeQueue(function(release) {
    setTimeout(function(){
      img = protect(img);
      console.log(img.width, img.height);
      var steps = Math.ceil(Math.log2(img.width / w));
      var sW = w * Math.pow(2, steps - 1);
      var sH = h * Math.pow(2, steps - 1);
      var x = 2;
      
      function run() {
        if ( ! (steps--)) {
          df.resolve(img);
          release();
          return;
        }
        
        setTimeout(function() {
          console.log(sW, sH);
          var canvas = document.createElement('canvas');
          canvas.width = sW;
          canvas.height = sH;
          canvas.getContext('2d').drawImage(img, 0, 0, sW, sH);
          img = canvas;
          sW = Math.round(sW / x);
          sH = Math.round(sH / x);
          run();
        }, 0);
      }
      run();
    }, 0);
  });
  return df.promise();
}
function imageLoader(src) {
  var df = $.Deferred();
  var img = new Image();
  img.onload = function() {
    df.resolve(img);
  };
  img.onerror = function() {
    df.reject(img);
  };
  img.src = src;
  return df.promise();
}
$('#file').on('change', function() {
  var images = $.map($('#file').prop('files'), function(file) {
    return imageLoader(URL.createObjectURL(file));
  });
  $.when.apply(null, images).done(function() {
    $.each(arguments, function(i, img) {
      var height = Math.round(width * img.height / img.width);
      resize(img, width, height).done(function(canvas) {
        $(img).attr({width: width, height: height});
        $('body').append(
          $("<p/>").append(
            [canvas]
          )
        );
      });
    });
  });
});
var progress = 0;
setInterval(function() {
  $('#progress').text("|/-\\"[progress % 4]);
  progress += 1;
}, 100);
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
hommpro
0viewers