Drag and Drop multiple images, resize them at client side and get resized images

时间:2018-02-03 09:19:15

标签: javascript jquery html css image-resizing

How can I drag and drop multiple image on HTML page, resize the images at client side and download the resized images to computer? I want to accomplish this without any server side processing.

I have tried below solution where one image can be uploaded (using drag and drop) and resized and shown on page, how can I extend this for multiple images?

// Required for drag and drop file access
	jQuery.event.props.push('dataTransfer');
	$(function(){
		var dropTimer;
		var dropTarget = $('.dragArea');
		var fileInput = $('#imageFile');
		dropTarget.on("dragover", function(event) {
			clearTimeout(dropTimer);
			if (event.currentTarget == dropTarget[0]) {
				dropTarget.addClass('over');
			}
			return false; // Required for drop to work
		});
		dropTarget.on('dragleave', function(event) {
			if (event.currentTarget == dropTarget[0]) {
				dropTimer = setTimeout(function() {
					dropTarget.removeClass('over');
				}, 200);
			}
		});
		handleDrop = function(files){
			dropTarget.removeClass('over');
			var file = files[0]; // Multiple files can be dropped. Lets only deal with the "first" one.
			if (file.type.match('image.*')) {
				resizeImage(file, 1000, function(result) {
					$('#resultImage').attr('src', result);
					$('.resultImageWrapper').show();
				});
			} else {
				alert("That file wasn't an image.");
			}
		};
		dropTarget.on('drop', function(event) {
			event.preventDefault(); // Or else the browser will open the file
			handleDrop(event.dataTransfer.files);
		});
		fileInput.on('change', function(event) {
			handleDrop(event.target.files);
		});
		resizeImage = function(file, size, callback) {
			var fileTracker = new FileReader;
			fileTracker.onload = function() {
				var image = new Image();
				image.onload = function(){
					var canvas = document.createElement("canvas");
					/*
					if(image.height > size) {
						image.width *= size / image.height;
						image.height = size;
					}
					*/
					if(image.width > size) {
						image.height *= size / image.width;
						image.width = size;
					}
					var ctx = canvas.getContext("2d");
					ctx.clearRect(0, 0, canvas.width, canvas.height);
					canvas.width = image.width;
					canvas.height = image.height;
					ctx.drawImage(image, 0, 0, image.width, image.height);
					callback(canvas.toDataURL("image/png"));
				};
				image.src = this.result;
			}
			fileTracker.readAsDataURL(file);
			fileTracker.onabort = function() {
				alert("The upload was aborted.");
			}
			fileTracker.onerror = function() {
				alert("An error occured while reading the file.");
			}
		};
	});
body {
			padding: 50px;
			font: 16px Helvetica;
		}
		.dragArea {
			background-color: #efefef;
			border: 3px dashed #cccccc;
			border-radius: 10px;
			text-align: center;
			padding: 50px;
		}
		.dragArea.over {
			border-color: #ff0000;
			background-color: #FFE9EA;
		}
		.resultImageWrapper {
			display: none;
			margin-top: 50px;
			text-align: center;
		}
		#resultImage {
			box-shadow: rgba(0,0,0,0.4) 0 2px 5px;
		}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!DOCTYPE html>
<html>
<head>
	<title>Angular HTML5 Preview, Crop And Upload</title>	
</head>
<body>

<div class="dragArea">
	<h3>Drag & Drop File Here</h3>
	<h4>Or Select File:</h4>
	<div>
		<input type="file" id="imageFile"/>
	</div>
</div>

<div class="resultImageWrapper">
	<img src="" alt="" id="resultImage" width="500" />
</div>

</body>
</html>

1 个答案:

答案 0 :(得分:0)

As one of the comment states, you are currently only dealing with one file. You will have to iterate through all the files if you want to handle multiple images:

// Required for drag and drop file access
jQuery.event.props.push('dataTransfer');
$(function() {
  var dropTimer;
  var dropTarget = $('.dragArea');
  var fileInput = $('#imageFile');
  dropTarget.on("dragover", function(event) {
    dropTarget.addClass('over');
    return false; // Required for drop to work
  });
  dropTarget.on('dragleave', function(event) {
    dropTarget.removeClass('over');
  });
  handleDrop = function(files) {
    dropTarget.removeClass('over');
    var file;
    // iterate through all dropped files
    for (var i = 0; i < files.length; i++) {
      file = files[i];
      if (file.type.match('image.*')) {
        resizeImage(file, 100, function(result) {
          // we now need to append a new Image instead of reusing a single one
          $('.resultImageWrapper').append(
            $('<img>', {src: result})
          )
          $('.resultImageWrapper').show();
        });
      } else {
        alert("That file wasn't an image.");
      }
    }
  };
  dropTarget.on('drop', function(event) {
    event.preventDefault(); // Or else the browser will open the file
    handleDrop(event.dataTransfer.files);
  });
  fileInput.on('change', function(event) {
    handleDrop(event.target.files);
  });
  resizeImage = function(file, size, callback) {
    // no need for a FileReader, a blobURI is better
    var image = new Image();
    image.onload = function() {
      var canvas = document.createElement("canvas");
      /*
      if(image.height > size) {
      	image.width *= size / image.height;
      	image.height = size;
      }
      */
      if (image.width > size) {
        image.height *= size / image.width;
        image.width = size;
      }
      var ctx = canvas.getContext("2d");
      canvas.width = image.width;
      canvas.height = image.height;
      ctx.drawImage(image, 0, 0, image.width, image.height);
      callback(canvas.toDataURL("image/png"));
    };
    image.src = URL.createObjectURL(file);

  };
});
body {
  padding: 50px;
  font: 16px Helvetica;
}

.dragArea {
  background-color: #efefef;
  border: 3px dashed #cccccc;
  border-radius: 10px;
  text-align: center;
  padding: 50px;
}

.dragArea.over {
  border-color: #ff0000;
  background-color: #FFE9EA;
}

.resultImageWrapper {
  display: none;
  margin-top: 50px;
  text-align: center;
}

.resultImageWrapper>img {
  box-shadow: rgba(0, 0, 0, 0.4) 0 2px 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="dragArea">
  <h3>Drag & Drop File Here</h3>
  <h4>Or Select File:</h4>
  <div>
    <input type="file" id="imageFile" />
  </div>
</div>

<div class="resultImageWrapper">

</div>