是的,可以做到。
它基于锚标签的新 html5“下载”属性。
流程应该是这样的:
- 加载图片
- 将图像绘制到画布中并指定裁剪边界
- 从画布中获取图像数据并使其成为 dom 中锚标记的
href 属性
- 将下载属性 (
download="desired-file-name") 添加到该 a 元素
而已。用户所要做的就是单击您的“下载链接”,图像将被下载到他的电脑上。
有机会我会回来做一个演示的。
更新
这是我承诺的the live demo。它采用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)。
因此,您仍然需要一个服务器端代理来为您的图像提供服务,就好像它托管在您的域上一样。
更新 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;
然后您所要做的就是将图像数据发布到此文件,它会将图像保存到光盘并返回现有图像文件名。
当然,这一切可能感觉有点复杂,但我想告诉你,你想要达到的目标是可能的。