本文介绍了在上传之前在浏览器中裁剪图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很多我找到的图书馆,例如Jcrop,实际上并没有进行剪裁,它只创建一个图像裁剪UI。然后它依赖于服务器进行实际裁剪。



如何通过使用一些HTML5将图像剪裁到客户端 功能不使用任何服务器端代码。



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

解决方案

是的,它可以完成。

它基于锚标记的新html5下载属性。

流量应该是这样的:


  1. 加载图像

  2. 将图像绘制到画布中指定的作物边界

  3. 从画布中获取图像数据,并为dom中的锚标记创建 href 属性
  4. li>
  5. 将下载属性( download =desired-file-name)添加到 a 元素
    就是这样。所有用户要做的就是点击你的下载链接,图像将被下载到他的电脑上。

如果有机会,我会带一个演示回来。



更新

这是根据我承诺的。它需要和作物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 =裁剪图像title =点击下载图像/>' ),
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('裁剪图像')
.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

忘记提及:当然还有一个缺点:(。

由于应用于图像的同源策略,如果你想访问图像的数据(通过画布方法 toDataUrl )。

因此,您仍然需要一个服务器端代理来为您的图像提供服务,就好像它托管在您的域中一样。



更新III
尽管我无法为此提供实时演示(出于安全原因),但下面是一个解决同源策略的php示例代码: p>

文件 proxy.php

  $ imgData = getimagesize($ _ GET ['img']); 
header(Content-type:。$ imgData ['mime']);
echo file_get_contents($ _ GET ['img']);

通过这种方式,不是直接从原点加载外部图像:

  img.src ='http://some-domain.com/imagef ile.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 /';
//生成随机名称
$ name = substr(md5(time()),10);
$ ext ='png';
$ imageName = $ path。$ name。'。'。$ ext;

//将图像写入磁盘
imagepng($ img,$ imageName);
imagedestroy($ img);
//返回图像路径
echo $ imageName;

您只需将图像数据发布到此文件即可将图像保存到光盘并返回现有的图像文件名。



当然这一切可能都有点复杂,但我想告诉你,你想要实现的目标是可能的。


Many libraries I have found, like Jcrop, do not actually do the cropping, it only creates an image cropping UI. It then depends on the server doing the actual cropping.

How can I make the image cropping client-side by using some HTML5 feature without using any server-side code.

If yes, are there some examples or hints?

解决方案

Yes, it can be done.
It is based on the new html5 "download" attribute of anchor tags.
The flow should be something like this :

  1. load the image
  2. draw the image into a canvas with the crop boundaries specified
  3. get the image data from the canvas and make it a href attribute for an anchor tag in the dom
  4. add the download attribute (download="desired-file-name") to that a elementThat's it. all the user has to do is click your "download link" and the image will be downloaded to his pc.

I'll come back with a demo when I get the chance.

Update
Here's the live demo as I promised. It takes the jsfiddle logo and crops 5px of each margin.
The code looks like this :

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';

Update II
Forgot to mention : of course there is a downside :(.
Because of the same-origin policy that is applied to images too, if you want to access an image's data (through the canvas method toDataUrl).
So you would still need a server-side proxy that would serve your image as if it were hosted on your domain.

Update IIIAlthough I can't provide a live demo for this (for security reasons), here is a php sample code that solves the same-origin policy :

file proxy.php :

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

This way, instead of loading the external image direct from it's origin :

img.src = 'http://some-domain.com/imagefile.png';

You can load it through your proxy :

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

And here's a sample php code for saving the image data (base64) into an actual image :

file 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;

All you have to do then is post the image data to this file and it will save the image to disc and return you the existing image filename.

Of course all this might feel a bit complicated, but I wanted to show you that what you're trying to achieve is possible.

这篇关于在上传之前在浏览器中裁剪图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 14:52