在上传之前在浏览器中裁剪图像
我发现的许多图书馆,如Jcrop,实际上并没有裁剪,它只创build一个图像裁剪UI。 然后取决于服务器做实际的裁剪。
如何使用某些HTML5function在不使用任何服务器端代码的情况下将图像剪裁到客户端 。
如果是,是否有一些例子或提示?
是的,可以做到。
它基于锚标签的新html5“下载”属性。
stream程应该是这样的:
- 加载图像
- 将图像绘制到指定了裁剪边界的canvas上
- 从canvas中获取图像数据,并将其作为dom中锚定标记的
href
属性 - 将下载属性(
download="desired-file-name"
)添加到该元素就是这样。 所有用户必须做的是点击你的“下载链接”,图像将被下载到他的电脑。
当我有机会时,我会回来演示。
更新
这是我承诺的现场演示 。 它需要jsfiddle徽标和作物5px的每个边距。
代码如下所示:
var img = new Image(); img.onload = function(){ var cropMarginWidth = 5, canvas = $('<canvas/>') .attr({ width: img.width - 2 * cropMarginWidth, height: img.height - 2 * cropMarginWidth }) .hide() .appendTo('body'), ctx = canvas.get(0).getContext('2d'), a = $('<a download="cropped-image" title="click to download the image" />'), cropCoords = { topLeft : { x : cropMarginWidth, y : cropMarginWidth }, bottomRight :{ x : img.width - cropMarginWidth, y : img.height - cropMarginWidth } }; ctx.drawImage(img, cropCoords.topLeft.x, cropCoords.topLeft.y, cropCoords.bottomRight.x, cropCoords.bottomRight.y, 0, 0, img.width, img.height); var base64ImageData = canvas.get(0).toDataURL(); a .attr('href', base64ImageData) .text('cropped image') .appendTo('body'); a .clone() .attr('href', img.src) .text('original image') .attr('download','original-image') .appendTo('body'); canvas.remove(); } img.src = 'some-image-src';
更新II
忘了提及:当然有一个缺点:(。
由于也应用于图像的同源策略,因此如果要访问图像的数据(通过canvas方法toDataUrl
)。
所以你仍然需要一个服务器端的代理服务器来为你的图像提供服务,就好像它托pipe在你的域名上一样。
更新III虽然我不能提供一个现场演示(出于安全原因),这是一个PHP示例代码,解决了同源策略:
文件proxy.php
:
$imgData = getimagesize($_GET['img']); header("Content-type: " . $imgData['mime']); echo file_get_contents($_GET['img']);
这样,而不是从它的原点直接加载外部图像:
img.src = 'http://some-domain.com/imagefile.png';
您可以通过您的代理加载它:
img.src = 'proxy.php?img=' + encodeURIComponent('http://some-domain.com/imagefile.png');
下面是一个用于将图像数据(base64)保存为实际图像的示例php代码:
文件save-image.php
:
$data = preg_replace('/data:image\/(png|jpg|jpeg|gif|bmp);base64/','',$_POST['data']); $data = base64_decode($data); $img = imagecreatefromstring($data); $path = 'path-to-saved-images/'; // generate random name $name = substr(md5(time()),10); $ext = 'png'; $imageName = $path.$name.'.'.$ext; // write the image to disk imagepng($img, $imageName); imagedestroy($img); // return the image path echo $imageName;
所有你需要做的就是将图像数据发布到这个文件,它将把图像保存到光盘,并返回你现有的图像文件名。
当然,这一切可能会有点复杂,但我想告诉你,你正在努力实现的是可能的。
Pixastic图书馆正是你想要的 。 但是,它只能在支持canvas的浏览器上运行。 对于那些较旧的浏览器,您可能需要:
- 提供服务器端回退,或者
- 告诉用户你很抱歉,但他需要一个更现代的浏览器。
当然,选项#2不是非常用户友好的。 但是,如果您的意图是提供纯粹的纯客户端工具,或者您不能支持回退后端裁剪(例如,您可能正在编写浏览器扩展程序或离线Chrome应用程序,或者您无法承受一个体面的托pipe服务提供商,提供图像操作库),那么限制您的用户群到现代浏览器可能是公平的。
编辑 :如果你不想学习Pixastic,我已经在jsFiddle 这里添加了一个非常简单的收割机。 应该可以通过drawCroppedImage
修改和整合和使用drawCroppedImage
函数。
#change-avatar-file
是一个文件input#change-avatar-file
是一个img标签(jcrop的目标)“key”是FR.onloadend事件https://developer.mozilla.org/en-US/docs /networking/ API /的FileReader
$('#change-avatar-file').change(function(){ var currentImg; if ( this.files && this.files[0] ) { var FR= new FileReader(); FR.onload = function(e) { $('#avatar-change-img').attr( "src", e.target.result ); currentImg = e.target.result; }; FR.readAsDataURL( this.files[0] ); FR.onloadend = function(e){ //console.log( $('#avatar-change-img').attr( "src")); var jcrop_api; $('#avatar-change-img').Jcrop({ bgFade: true, bgOpacity: .2, setSelect: [ 60, 70, 540, 330 ] },function(){ jcrop_api = this; }); } } });
如果你仍然使用JCrop,你将只需要这个PHP函数来裁剪文件:
$img_src = imagecreatefromjpeg($src); $img_dest = imagecreatetruecolor($new_w,$new_h); imagecopyresampled($img_dest,$img_src,0,0,$x,$y,$new_w,$new_h,$w,$h); imagejpeg($img_dest,$dest);
客户端:
jQuery(function($){ $('#target').Jcrop({ onChange: showCoords, onSelect: showCoords, onRelease: clearCoords }); }); var x,y,w,h; //these variables are necessary to crop function showCoords(c) { x = cx; y = cy; w = cw; h = ch; }; function clearCoords() { x=y=w=h=0; }