我发现许多库,如Jcrop等,实际上并未进行裁剪,而只是创建了一个图像裁剪用户界面。它还依赖于服务器来执行实际的裁剪。
我如何使用一些 HTML5特性 在不使用任何服务器端代码的情况下,使图像裁剪在客户端进行呢?
如果可以,是否有一些示例或提示可以提供?
我发现许多库,如Jcrop等,实际上并未进行裁剪,而只是创建了一个图像裁剪用户界面。它还依赖于服务器来执行实际的裁剪。
我如何使用一些 HTML5特性 在不使用任何服务器端代码的情况下,使图像裁剪在客户端进行呢?
如果可以,是否有一些示例或提示可以提供?
可以完成这个操作。这基于HTML5中新的锚标签“download”属性。 流程如下:
download="desired-file-name"
)就是这样。用户只需点击您的“下载链接”,即可将图像下载到他的电脑上。
我有机会时会回来展示演示。
这里是我承诺的实时演示,它使用了JSFiddle logo并裁剪了每个边距的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';
忘了提一点:当然还有一个缺点 :(。
由于同源策略也适用于图像,如果您想通过画布方法toDataUrl
访问图像数据,
因此,仍需要一个服务器端代理,将您的图像作为托管在您域上的图像提供。
虽然我无法提供此功能的实时演示(出于安全原因),但以下是解决同源策略的 PHP 示例代码:
文件 proxy.php
:
$imgData = getimagesize($_GET['img']);
header("Content-type: " . $imgData['mime']);
echo file_get_contents($_GET['img']);
这种方式,不再直接从其源加载外部图像:
img.src = 'http://example.com/imagefile.png';
您可以通过代理加载它:
img.src = 'proxy.php?img=' + encodeURIComponent('http://example.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;
然后你所要做的就是将图像数据发布到此文件中,它将保存该图像并返回现有图像的文件名。
当然,所有这些可能感觉有点复杂,但我想展示给你,你想实现的是可能的。
drawCroppedImage
函数。toDataURL
从画布中获取base64编码的图像数据。如果在裁剪后在URL栏中输入 javascript:window.open($("#demoimage")[0].toDataURL())
,则会看到裁剪后的图像本身。 - apsillersjavascript:
部分;请确保将其添加回去。) - apsillers#change-avatar-file
是一个文件上传输入框
#change-avatar-file
是一个图片标签(jcrop的目标)
“key” 是 FR.onloadend 事件
https://developer.mozilla.org/en-US/docs/Web/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;
});
}
}
});
$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 = c.x;
y = c.y;
w = c.w;
h = c.h;
};
function clearCoords()
{
x=y=w=h=0;
}
HTML5 canvas
来完成 PHP 代码所做的同样工作吗? - Lorraine Bernard