在上传到服务器之前,使用JavaScript调整客户端大小的图像

ger*_*aud 142 javascript resize image client-side

我正在寻找一种方法来使用JavaScript调整客户端图像的大小(实际上调整大小,而不仅仅是更改宽度和高度).
我知道可以在Flash中完成它但我想尽可能避免它.

网上某处有开源算法吗?

小智 103

这是一个要点:https: //gist.github.com/dcollien/312bce1270a5f511bf4a

(es6版本和.js版本,可以包含在脚本标记中)

您可以按如下方式使用它:

<input type="file" id="select">
<img id="preview">
<script>
document.getElementById('select').onchange = function(evt) {
    ImageTools.resize(this.files[0], {
        width: 320, // maximum width
        height: 240 // maximum height
    }, function(blob, didItResize) {
        // didItResize will be true if it managed to resize it, otherwise false (and will return the original file as 'blob')
        document.getElementById('preview').src = window.URL.createObjectURL(blob);
        // you can also now upload this blob using an XHR.
    });
};
</script>
Run Code Online (Sandbox Code Playgroud)

它包括一堆支持检测和polyfill,以确保它可以在尽可能多的浏览器上运行.

(它也忽略了gif图像 - 如果它们是动画的)

  • 嗯..我在这方面取得了很大的成功,但我发现我的图像(除了被调整大小)也遭受了巨大的质量损失(以严重的像素化形式),尽管它以正确的分辨率输出. (4认同)
  • 对于任何质量损失(重新采样)的人,更新画布上下文以将`imageSmoothingEnabled`设置为true`并将`imageSmoothingQuality`设置为`high`.在blockcript中,块看起来像:`const ctx = canvas.getContext('2d'); ctx.imageSmoothingEnabled = true; (ctx as any).imageSmoothingQuality ='high'; ctx.drawImage(image,0,0,width,height);` (3认同)
  • 我觉得你没有得到足够的赞誉 - 我认为这很有效,而且非常简单.感谢分享! (2认同)

小智 58

答案是肯定的 - 在HTML 5中,您可以使用canvas元素调整客户端图像的大小.您还可以获取新数据并将其发送到服务器.看本教程:

http://hacks.mozilla.org/2011/01/how-to-develop-a-html5-image-uploader/

  • 这是一个**链接答案**,因此应该是一个评论. (24认同)
  • canvas.mozGetAsFile("foo.png"); 是一个不推荐使用的函数 (2认同)

小智 12

如果你在上传前调整大小我刚刚发现这个 http://www.plupload.com/

它以任何可以想象的方式为您提供所有魔力.

不幸的是,Mozilla浏览器仅支持HTML5调整大小,但您可以将其他浏览器重定向到Flash和Silverlight.

我刚尝试过,它与我的机器人一起工作!

我在flash 中使用http://swfupload.org/,它可以很好地完成工作,但调整大小非常小.(不记得限制)并且当flash不可用时不会返回到html4.

  • 当用户尝试上传仅将存储为更小的照片的10mb照片时,进行客户端调整大小是很好的.它会以这种方式上传得更快. (44认同)
  • 小心,因为 plupload 是 AGPL。 (2认同)

Vit*_*aly 10

http://nodeca.github.io/pica/demo/

在现代浏览器中,您可以使用画布来加载/保存图像数据.但是如果你在客户端调整图像大小,你应该记住几件事:

  1. 每个通道只有8位(jpeg可以有更好的动态范围,大约12位).如果你没有上传专业照片,那应该不是问题.
  2. 关于调整大小算法要小心.大多数客户端调整器使用琐碎的数学,结果比实际情况更糟.
  3. 您可能需要锐化缩小的图像.
  4. 如果您希望重用原始元数据(exif和其他),请不要忘记删除颜色配置文件信息.因为它是在将图像加载到画布时应用的.


Dav*_* V. 6

也许使用canvas标签(尽管它不可​​移植).有一个关于如何在这里用画布旋转图像的博客,我想如果你可以旋转它,你可以调整它的大小.也许它可以成为一个起点.

也.

  • 非常有用的例子。您可能想在答案中添加一两个片段,以防这些链接中断。 (2认同)

Gab*_*njo 5

在将图像上传到服务器之前,您可以使用 javascript 图像处理框架进行客户端图像处理。

下面我使用MarvinJ根据以下页面中的示例创建了一个可运行的代码: “在将图像上传到服务器之前在客户端处理图像”

基本上我使用Marvin.scale(...)方法来调整图像大小。然后,我将图像作为 blob 上传(使用方法image.toBlob())。服务器回复提供接收图像的 URL。

/***********************************************
 * GLOBAL VARS
 **********************************************/
var image = new MarvinImage();

/***********************************************
 * FILE CHOOSER AND UPLOAD
 **********************************************/
 $('#fileUpload').change(function (event) {
	form = new FormData();
	form.append('name', event.target.files[0].name);
	
	reader = new FileReader();
	reader.readAsDataURL(event.target.files[0]);
	
	reader.onload = function(){
		image.load(reader.result, imageLoaded);
	};
	
});

function resizeAndSendToServer(){
  $("#divServerResponse").html("uploading...");
	$.ajax({
		method: 'POST',
		url: 'https://www.marvinj.org/backoffice/imageUpload.php',
		data: form,
		enctype: 'multipart/form-data',
		contentType: false,
		processData: false,
		
	   
		success: function (resp) {
       $("#divServerResponse").html("SERVER RESPONSE (NEW IMAGE):<br/><img src='"+resp+"' style='max-width:400px'></img>");
		},
		error: function (data) {
			console.log("error:"+error);
			console.log(data);
		},
		
	});
};

/***********************************************
 * IMAGE MANIPULATION
 **********************************************/
function imageLoaded(){
  Marvin.scale(image.clone(), image, 120);
  form.append("blob", image.toBlob());
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.marvinj.org/releases/marvinj-0.8.js"></script>
<form id="form" action='/backoffice/imageUpload.php' style='margin:auto;' method='post' enctype='multipart/form-data'>
				<input type='file' id='fileUpload' class='upload' name='userfile'/>
</form><br/>
<button type="button" onclick="resizeAndSendToServer()">Resize and Send to Server</button><br/><br/>
<div id="divServerResponse">
</div>
Run Code Online (Sandbox Code Playgroud)