如何在表单中的输入类型=“文件”中添加图像并在同一表单上提交它们之后生成缩略图图像

我有一个允许用户上传图片的表格。 在用户提交表单后,我想在前端生成每张图片的缩略图,然后将其存储在服务器上。

出于安全原因,无法更改文件输入字段的值,因此如何向服务器发送在js中在前端生成的一些缩略图图像?

在表单提交之前,是否可以在前端从输入文件字段中的图像集生成缩略图? 然后同时提交两个?

我找到了这个更简单但function强大的教程 。 它只是创建一个img元素,并使用fileReader对象将其source属性指定为表单输入的值

 function previewFile() { var preview = document.querySelector('img'); var file = document.querySelector('input[type=file]').files[0]; var reader = new FileReader(); reader.onloadend = function () { preview.src = reader.result; } if (file) { reader.readAsDataURL(file); } else { preview.src = ""; } } 
 
Image preview...

经过更好的在线搜索,我找到了问题的答案。

可以将canvasFile API结合使用。

尝试上传下面演示中的任何图片,并看到新生成的缩略图将显示在表单的右侧。

演示: http //jsfiddle.net/a_incarnati/fua75hpv/

 function handleImage(e){ var reader = new FileReader(); reader.onload = function(event){ var img = new Image(); img.onload = function(){ canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img,0,0); } img.src = event.target.result; } reader.readAsDataURL(e.target.files[0]); } 

DerekR对这个问题给出了一个很好的答案:

如何将图像上传到HTML5canvas

TL; DR: 见JSFiddle

因为我想通过API上传图像并显示图像的预览(两件事实际上彼此很好),我想出了这个:

 (function(angular) { angular .module('app') .directive('inputFilePreview', [function() { var canvas, mapToModel, elementScope; /** * To be fired when the image has been loaded */ var imageOnLoad = function(){ canvas.width = this.width; canvas.height = this.height; canvas.getContext("2d").drawImage(this,0,0); }; /** * To be fired when the FileReader has loaded * @param loadEvent {{}} */ var readerOnLoad = function(loadEvent){ var img = new Image(); img.onload = imageOnLoad; img.src = loadEvent.target.result; if(mapToModel) { setModelValue(elementScope, mapToModel, img.src); } }; /** * This allows us to set the value of a model in the scope of the element (or global scope if the * model is an object) * @param scope {{}} * @param modelReference {string} * @param value {*} */ var setModelValue = function(scope, modelReference, value) { // If the model reference refers to the propery of an object (eg. "object.property") if(~modelReference.indexOf('.')) { var parts = modelReference.split('.', 2); // Only set the value if that object already exists if(scope.hasOwnProperty(parts[0])) { scope[parts[0]][parts[1]] = value; return; } } scope[modelReference] = value; }; /** * The logic for our directive * @param scope {{}} * @param element {{}} * @param attributes {{}} */ var link = function(scope, element, attributes) { elementScope = scope; canvas = document.getElementById(attributes.inputFilePreview); if(attributes.hasOwnProperty('mapToModel')) { mapToModel = attributes.mapToModel; } element.on('change', function(changeEvent) { var reader = new FileReader(); reader.onload = readerOnLoad; reader.readAsDataURL(changeEvent.target.files[0]); }); }; return { restrict: 'A', link: link }; }]); })(angular); 

预览工作所需的两个元素是:

   

片段遵循:

 (function (angular) { angular.module('app', []) .directive('inputFilePreview', [function () { var canvas, mapToModel, elementScope; /** * To be fired when the image has been loaded */ var imageOnLoad = function () { canvas.width = this.width; canvas.height = this.height; canvas.getContext("2d").drawImage(this, 0, 0); }; /** * To be fired when the FileReader has loaded * @param loadEvent {{}} */ var readerOnLoad = function (loadEvent) { var img = new Image(); img.onload = imageOnLoad; img.src = loadEvent.target.result; if (mapToModel) { setModelValue(elementScope, mapToModel, img.src); } }; /** * This allows us to set the value of a model in the scope of the element (or global scope if the * model is an object) * @param scope {{}} * @param modelReference {string} * @param value {*} */ var setModelValue = function (scope, modelReference, value) { // If the model reference refers to the propery of an object (eg. "object.property") if (~modelReference.indexOf('.')) { var parts = modelReference.split('.', 2); // Only set the value if that object already exists if (scope.hasOwnProperty(parts[0])) { scope[parts[0]][parts[1]] = value; return; } } scope[modelReference] = value; }; /** * The logic for our directive * @param scope {{}} * @param element {{}} * @param attributes {{}} */ var link = function (scope, element, attributes) { elementScope = scope; canvas = document.getElementById(attributes.inputFilePreview); if (attributes.hasOwnProperty('mapToModel')) { mapToModel = attributes.mapToModel; } element.on('change', function (changeEvent) { var reader = new FileReader(); reader.onload = readerOnLoad; reader.readAsDataURL(changeEvent.target.files[0]); }); }; return { restrict: 'A', link: link }; }]) .controller('UploadImageController', [ '$scope', function ($scope) { $scope.image = { title: 'Test title' }; $scope.send = function (data) { $scope.sentData = JSON.stringify(data, null, 2); return false; }; }]); })(angular); 
 canvas { max-height: 300px; max-width: 300px; } 
  



{{sentData}}

认为可能值得添加更现代的答案并引用MDN Web Docs 。

您可以在输入元素上添加“更改”的事件侦听器,然后通过this.files访问文件列表来显示所选图像的缩略图(如MDN示例所示)。 这是我最近的一个实施。 uploadWatermark是

 uploadWatermark.addEventListener('change', function(){ const file = this.files[0]; if (file.type.startsWith('image/')) { const img = document.createElement('img'); const watermarkPreview = document.getElementById("uploaded-watermark"); img.classList.add("prev-thumb"); img.file = file; watermarkPreview.appendChild(img); const reader = new FileReader(); reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }})(img); reader.readAsDataURL(file); } });