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

新手上路,请多包涵

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

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

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

原文由 Lorraine Bernard 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 268
1 个回答

是的,这是可以做到的。它基于锚标记的新 HTML5“下载”属性。流程应该是这样的:

  1. 加载图像
  2. 将图像绘制到指定裁剪边界的画布中
  3. 从画布获取图像数据并将其 href DOM 中锚标记的属性
  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';

忘了说:当然有一个缺点 :(。由于同源策略也适用于图像,如果你想访问图像的数据(通过画布方法 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;

您所要做的就是将图像数据发布到此文件,它会将图像保存到光盘并返回给您现有的图像文件名。

当然,所有这一切可能感觉有点复杂,但我想向您展示您正在努力实现的目标是可能的。

原文由 gion_13 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏