在上传之前在浏览器中裁剪图像

Lor*_*ard 58 javascript html5 html5-canvas

我发现的许多库,如Jcrop,实际上并没有进行裁剪,它只创建了一个图像裁剪UI.然后它取决于服务器进行实际裁剪.

如何在不使用任何服务器端代码的情况下使用某些HTML5功能客户端进行图像裁剪.

如果是,是否有一些例子或提示?

gio*_*_13 43

是的,可以做到.
它基于锚标签的新html5"下载"属性.
流程应该是这样的:

  1. 加载图像
  2. 将图像绘制到指定了裁剪边界的画布中
  3. 从画布中获取图像数据,并使其成为hrefdom中锚标记的属性
  4. 将下载属性(download="desired-file-name")添加到该a元素就是这样.用户只需点击"下载链接",图像就会下载到他的电脑上.

当我有机会的时候,我会带回演示.

更新
这是我承诺的现场演示.它需要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';
Run Code Online (Sandbox Code Playgroud)

更新II
忘了提及:当然有一个缺点:(.
由于同样的原始政策也应用于图像,如果你想访问图像的数据(通过画布方法toDataUrl).
所以你仍然需要一个服务器端代理,可以为您的映像提供服务,就好像它是在您的域上托管一样.

更新III 虽然我无法为此提供实时演示(出于安全原因),这里有一个php示例代码,它解决了同源策略:

档案 proxy.php:

$imgData = getimagesize($_GET['img']);
header("Content-type: " . $imgData['mime']);
echo file_get_contents($_GET['img']);  
Run Code Online (Sandbox Code Playgroud)

这样,而不是直接从它的原点加载外部图像:

img.src = 'http://some-domain.com/imagefile.png';
Run Code Online (Sandbox Code Playgroud)

您可以通过代理加载它:

img.src = 'proxy.php?img=' + encodeURIComponent('http://some-domain.com/imagefile.png');  
Run Code Online (Sandbox Code Playgroud)

这里有一个示例php代码,用于将图像数据(base64)保存到实际图像中:

档案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;
Run Code Online (Sandbox Code Playgroud)

然后,您只需将图像数据发布到此文件,它就会将图像保存到光盘并返回现有的图像文件名.

当然所有这些可能会感觉有点复杂,但我想告诉你,你想要实现的目标是可能的.


aps*_*ers 7

Pixastic库不正是你想要的.但是,它仅适用于具有画布支持的浏览器.对于那些旧版浏览器,您需要:

  1. 提供服务器端后备,或
  2. 告诉用户你很抱歉,但他需要一个更现代的浏览器.

当然,选项#2不是非常用户友好.但是,如果您的目的是提供纯粹的仅限客户端的工具和/或您无法支持后备后端裁剪器(例如,您可能正在编写浏览器扩展程序或离线Chrome应用程序,或者您可能负担不起一个体面的托管服务提供商,提供图像处理库),然后将您的用户群限制在现代浏览器可能是公平的.

编辑:如果你不想学Pixastic,我已经添加的jsfiddle一个非常简单的农作物在这里.应该可以修改和集成并使用drawCroppedImageJcrop 的功能.

  • 你在寻找https://github.com/jseidelin/pixastic吗? (2认同)
  • 不幸的是,看起来Pixastic项目已经死了 (2认同)