站长图库

Laravel 结合前端剪切插件实现图片裁剪及无刷新上传

󰌂发布时间 2020-08-15 热度 143

 当前位置:  首页 / 教程资源 / 后端教程

教程内容:

一、需求

使用的插件:

    后台服务使用 laravel 5.5 构建
    laravel 使用 intervetion/image 进行图片裁剪处理
    前端使用文件上传插件即可
    jquery 裁剪插件使用 zui.imgcutter.min.js

使用什么裁剪插件无所谓,使用 zui.imgcutter.min.js 的原因是这种思想符合想要实现的思想。

思想如下:

    使用无刷新上传插件将图片上传到服务器
    返回图片 url 到前端界面进行显示
    调用 图片裁剪插件 前端显示对图片进行裁剪
    提交到后台的时候,将裁剪的 尺寸 和 x/y 坐标 发送到后端
    后端对图片进行裁剪工作并重新保存覆盖原来的图片

二、详细流程
1、文件上传

为了优化体验,用户选择文件进行文件上传,后端将文件保存即可,同时返回保存的图片 url。

图片上传最终需要的实际上就是保存的 url,而返回的 url 也需要在页面上显示并且用户构造剪切插件使用。
2、图片显示及裁剪

最终我们需要的是在后端进行图片的处理,因此上传后使用返回的 url,并且构建剪切插件:

我使用的是:http://zui.sexy/#javascript/imgcutter

这个插件可以单独引入使用,思想和上面的思想一样。
3、获取裁剪的宽度高度和 x/y 坐标

intervetion/image 处理图片的时候,需要使用 width,height,x,y坐标

获取到这些信息后,我的处理方式是将这些信息进行 JSON.stringfy() ,同样在提交的时候发送给后端处理。

因此后端拿到数据的时候,也会拿到裁剪的这些信息。
4、后端接收信息进行处理

如果要使用 intervetion/image ,composer 安装即可:

composer require intervetion/image


加入 laravel 的 providers 中:

编辑 config/app.php:

$providers 添加 Intervention\Image\ImageServiceProvider::class
$aliases 添加 Image' => Intervention\Image\Facades\Image::class


引入Image的时候直接使用:

use Intervention\Image\Facades\Image;


// 修改图片尺寸 并且保存为相同的图片路径 将之前的文件覆盖掉

    protected function reSaveImage($url, $imageData)
    {
        $img = Image::make('uploads/'.$url)->resize($imageData['naturalWidth'],null,function($constraint){
            $constraint->aspectRatio();
        })->crop(intval($imageData['width']),intval($imageData['height']),$imageData['left'],$imageData['top']);
        $img->save();
    }

关于 intervetion/image 更多更详细的 API 介绍,可以查看:

    http://blog.csdn.net/beyond__devil/article/details/62230610

上面的函数根据实际使用场景使用的,其中 $url 就是 path,也就是上传的文件的保存路径,其次,$imageData 是图片裁剪插件进行的 json 数据,在这之前已经使用 json_decode($jsonData, true) 进行解析了,因此可以直接使用。

$img->save() 能够直接覆盖原来的图片,这样不会造成保存两张图片的尴尬局面。
三、注意点

由于图片在页面上渲染的时候,可能并不是图片的真实宽度,因此如果还是按照裁剪的宽度和高度以及 x/y 坐标来处理,必定会出现问题。

上面的问题有两种解决方法:
1、解决方式一:resize 服务端图像,保证两者图片一致

在 reSaveImage 函数中,你可以发现一个$imageData['naturalWith'] 属性,这个属性实际上是我自己得到的,并不是 imgcutter.js 插件自己有的。

naturakWidth 实际上就是获取的图片渲染的宽度,而我在 reSaveImage() 方法中,使用了 resize(),将图片宽度压缩或者提高到 naturalWidth ,从而保证服务端保存的图片和前端裁剪时渲染的图片使用的是相同宽度,这样子就能保存裁剪的样子就是需要的样子。

这种方式也有缺点,对服务端保存的图片实际上是进行了尺寸变化,虽然这种尺寸变化是等比例的,还是先变化图片,再进行裁剪。
2、解决方式二:通过比例计算,计算新的裁剪宽高和 x/y 坐标

如果不想对服务端的图片进行变化,则可以在服务端获取图片的宽度,然后通过和 $imageData['naturalWidth'] 进行比例计算,通过这个比例来调整 $imageData['width']、$imageData['height']、$imageData['left']、$imageData['top'],这样子裁剪的时候,通过比例调整可以直接在原图像上进行裁剪。

归根结底, 获取前端裁剪时图片的渲染宽度是非常关键的

虽然 html5 提供了一个 naturalWidth 用来获取图片的原始尺寸,但是我这里的 naturalWidth 是渲染尺寸,主要是为了不想和 imgcutter.js 中的 width 冲突罢了。

评论(0)条

    站长图库

    站长素材 - 建站资源分享平台

    虚拟库提供各类虚拟产品,虚拟资源以及教程、模板、素材等,虚拟库是一个互联网虚拟产品,虚拟资源聚集地的特色网站!

    反馈建议

    kefu@xuniku.cn fuwu@xuniku.cn

    周一至周日9:00-23:00

    在线QQ咨询

    本期推荐小程序

    本站所有资源均为会员提供或网上搜集,版权归原作者所有,如需商业用途或转载请与原作者联系!所提供的内容仅供观摩学习交流之用,请勿用作商业用途!如有侵权,请及时 联系我们 删除

    Powered by 虚拟库 © 2010-2020 流量联盟   copyright   北京流量圈信息科技有限公司