【jQuery插件分享】Cropper——一个简单方便的图片裁剪插件
原文:https://segmentfault.com/a/1190000012344970
插件介绍
这是一个我在写以前的项目的途中发现的一个国人写的jQuery图像裁剪插件,当时想实现用户资料的头像上传功能,并且能够预览图片,和对图片进行简单的裁剪、旋转,花了不少时间才看到了这个插件,感觉功能挺全面,代码实现起来也挺简单,再加上用的是Bootstrap,对移动端操作也有适配,于是就用了。现在稍微有点时间就记录一下,方便以后再用的时候查阅。另外也有对应的js版本。
官方文档(英文)
jQuery
js
兼容性
兼容所有支持了Canvas的浏览器(IE9+),一小部分功能例外,具体请查看官方文档。
得到裁剪到的图像的canvas,如果没有裁剪,那么就返回的是整个原图图像的canvas。
这是最重要的一个方法,通过这个方法就可以得到裁剪后的图像,再使用toDataURL()
得到base64 dataURL(不指定格式的话会是png格式)或者toBlob()
得到Blob,然后就可以很轻松地将图片上传至服务器上或者显示在某个img标签中了。例如:
- // 转换为png格式的dataURL
- var dataURL = $().cropper('getCroppedCanvas', {
- width:100,
- height:100
- }).toDataURL('image/png');
- // 转换为Blob后显示在img标签中
- var URL = window.URL || window.webkitURL;
- $().cropper('getCroppedCanvas', {
- width:100,
- height:100
- }).toBlob(function (blob) {
- $().attr('src',URL.createObjectURL(blob));
- });
简单实例
在页面直接使用cropper
接下来只是实现一个简单的功能:网页中可以上传图片,然后对图片进行裁剪,点击确定后会显示出裁剪后的图片。
代码如下:
- <!DOCTYPE html>
- <html lang="zh-cn">
- <head>
- <meta charset="UTF-8">
- <title>裁剪图片</title>
- <link href="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.css" rel="stylesheet">
- <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
- <style>
- .row{
- margin-bottom: 5px;
- }
- #photo {
- max-width: 100%;
- }
- .img-preview {
- width: 100px;
- height: 100px;
- overflow: hidden;
- }
- button {
- margin-top:10px;
- }
- #result {
- width: 150px;
- height: 150px;
- }
- </style>
- </head>
- <body>
- <div class="container">
- <div class="row">
- <div class="col-sm-12 text-center">
- <label for="input" class="btn btn-danger" id="">
- <span>选择图片</span>
- <input type="file" id="input" class="sr-only">
- </label>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-6 col-sm-offset-2">
- <img src="" id="photo">
- </div>
- <div class="col-sm-2">
- <div>
- <p>
- 预览(100*100):
- </p>
- <div class="img-preview">
- </div>
- </div>
- <button class="btn btn-primary" onclick="crop()">裁剪图片</button>
- <div>
- <br/>
- <p>
- 结果:
- </p>
- <img src="" alt="裁剪结果" id="result">
- </div>
- </div>
- </div>
- </div>
- <!-- Scripts -->
- <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
- <script src="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.js"></script>
- <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
- <script>
- // 修改自官方demo的js
- var initCropper = function (img, input){
- var $image = img;
- var options = {
- aspectRatio: 1, // 纵横比
- viewMode: 2,
- preview: '.img-preview' // 预览图的class名
- };
- $image.cropper(options);
- var $inputImage = input;
- var uploadedImageURL;
- if (URL) {
- // 给input添加监听
- $inputImage.change(function () {
- var files = this.files;
- var file;
- if (!$image.data('cropper')) {
- return;
- }
- if (files && files.length) {
- file = files[0];
- // 判断是否是图像文件
- if (/^image\/\w+$/.test(file.type)) {
- // 如果URL已存在就先释放
- if (uploadedImageURL) {
- URL.revokeObjectURL(uploadedImageURL);
- }
- uploadedImageURL = URL.createObjectURL(file);
- // 销毁cropper后更改src属性再重新创建cropper
- $image.cropper('destroy').attr('src', uploadedImageURL).cropper(options);
- $inputImage.val('');
- } else {
- window.alert('请选择一个图像文件!');
- }
- }
- });
- } else {
- $inputImage.prop('disabled', true).addClass('disabled');
- }
- }
- var crop = function(){
- var $image = $('#photo');
- var $target = $('#result');
- $image.cropper('getCroppedCanvas',{
- width:300, // 裁剪后的长宽
- height:300
- }).toBlob(function(blob){
- // 裁剪后将图片放到指定标签
- $target.attr('src', URL.createObjectURL(blob));
- });
- }
- $(function(){
- initCropper($('#photo'),$('#input'));
- });
- </script>
- </body>
- </html>
在bootstrap模态框中使用cropper
虽然在模态框中可以像上面一样使用cropper,甚至我以前写的项目也是跟上面一样,但是这次整理的时候突然发现了一个bug:当隐藏模态框后调整浏览器大小(甚至按f12),再打开模态框后cropper的容器会改变,导致难以使用。于是,我在GitHub中翻找了issue,在官方的example中找到了对应的解决方法。但其实这个解决方法也是一种暴力解法,即模态框隐藏后销毁cropper,打开后重新创建cropper,可能会有别的方法,因为不确定会不会有别的bug,所以暂时还是用官方的方法比较好。
代码如下:
- <!DOCTYPE html>
- <html lang="zh-cn">
- <head>
- <meta charset="UTF-8">
- <title>上传头像</title>
- <link href="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.css" rel="stylesheet">
- <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
- <style type="text/css">
- body{
- text-align: center;
- }
- #user-photo {
- width:300px;
- height:300px;
- margin-top: 10px;
- }
- #photo {
- max-width:100%;
- max-height:350px;
- }
- .img-preview-box {
- text-align: center;
- }
- .img-preview-box > div {
- display: inline-block;;
- margin-right: 10px;
- }
- .img-preview {
- overflow: hidden;
- }
- .img-preview-box .img-preview-lg {
- width: 150px;
- height: 150px;
- }
- .img-preview-box .img-preview-md {
- width: 100px;
- height: 100px;
- }
- .img-preview-box .img-preview-sm {
- width: 50px;
- height: 50px;
- border-radius: 50%;
- }
- </style>
- </head>
- <body>
- <button class="btn btn-primary" data-target="#changeModal" data-toggle="modal">打开</button><br/>
- <div class="user-photo-box">
- <img id="user-photo" src="">
- </div>
- </div>
- <div class="modal fade" id="changeModal" tabindex="-1" role="dialog" aria-hidden="true">
- <div class="modal-dialog">
- <div class="modal-content">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
- <h4 class="modal-title text-primary">
- <i class="fa fa-pencil"></i>
- 更换头像
- </h4>
- </div>
- <div class="modal-body">
- <p class="tip-info text-center">
- 未选择图片
- </p>
- <div class="img-container hidden">
- <img src="" alt="" id="photo">
- </div>
- <div class="img-preview-box hidden">
- <hr>
- <span>150*150:</span>
- <div class="img-preview img-preview-lg">
- </div>
- <span>100*100:</span>
- <div class="img-preview img-preview-md">
- </div>
- <span>30*30:</span>
- <div class="img-preview img-preview-sm">
- </div>
- </div>
- </div>
- <div class="modal-footer">
- <label class="btn btn-danger pull-left" for="photoInput">
- <input type="file" class="sr-only" id="photoInput" accept="image/*">
- <span>打开图片</span>
- </label>
- <button class="btn btn-primary disabled" disabled="true" onclick="sendPhoto();">提交</button>
- <button class="btn btn-close" aria-hidden="true" data-dismiss="modal">取消</button>
- </div>
- </div>
- </div>
- </div>
- <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
- <script src="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.js"></script>
- <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
- <script type="text/javascript">
- var initCropperInModal = function(img, input, modal){
- var $image = img;
- var $inputImage = input;
- var $modal = modal;
- var options = {
- aspectRatio: 1, // 纵横比
- viewMode: 2,
- preview: '.img-preview' // 预览图的class名
- };
- // 模态框隐藏后需要保存的数据对象
- var saveData = {};
- var URL = window.URL || window.webkitURL;
- var blobURL;
- $modal.on('show.bs.modal',function () {
- // 如果打开模态框时没有选择文件就点击“打开图片”按钮
- if(!$inputImage.val()){
- $inputImage.click();
- }
- }).on('shown.bs.modal', function () {
- // 重新创建
- $image.cropper( $.extend(options, {
- ready: function () {
- // 当剪切界面就绪后,恢复数据
- if(saveData.canvasData){
- $image.cropper('setCanvasData', saveData.canvasData);
- $image.cropper('setCropBoxData', saveData.cropBoxData);
- }
- }
- }));
- }).on('hidden.bs.modal', function () {
- // 保存相关数据
- saveData.cropBoxData = $image.cropper('getCropBoxData');
- saveData.canvasData = $image.cropper('getCanvasData');
- // 销毁并将图片保存在img标签
- $image.cropper('destroy').attr('src',blobURL);
- });
- if (URL) {
- $inputImage.change(function() {
- var files = this.files;
- var file;
- if (!$image.data('cropper')) {
- return;
- }
- if (files && files.length) {
- file = files[0];
- if (/^image\/\w+$/.test(file.type)) {
- if(blobURL) {
- URL.revokeObjectURL(blobURL);
- }
- blobURL = URL.createObjectURL(file);
- // 重置cropper,将图像替换
- $image.cropper('reset').cropper('replace', blobURL);
- // 选择文件后,显示和隐藏相关内容
- $('.img-container').removeClass('hidden');
- $('.img-preview-box').removeClass('hidden');
- $('#changeModal .disabled').removeAttr('disabled').removeClass('disabled');
- $('#changeModal .tip-info').addClass('hidden');
- } else {
- window.alert('请选择一个图像文件!');
- }
- }
- });
- } else {
- $inputImage.prop('disabled', true).addClass('disabled');
- }
- }
- var sendPhoto = function(){
- $('#photo').cropper('getCroppedCanvas',{
- width:300,
- height:300
- }).toBlob(function(blob){
- // 转化为blob后更改src属性,隐藏模态框
- $('#user-photo').attr('src',URL.createObjectURL(blob));
- $('#changeModal').modal('hide');
- });
- }
- $(function(){
- initCropperInModal($('#photo'),$('#photoInput'),$('#changeModal'));
- });
- </script>
- </body>
- </html>
使用cropper来上传图片到服务器
由于cropper可以得到两种裁剪后图片的数据(即blob和dataURL),所以对应的上传到后台也会有两种方法,在这里我只写一种使用ajax上传base64 dataURL的,另一种方法如果有兴趣,可以自己尝试。
页面中,将上面的sendPhoto方法改为:
- var sendPhoto = function () {
- // 得到PNG格式的dataURL
- var photo = $('#photo').cropper('getCroppedCanvas', {
- width: 300,
- height: 300
- }).toDataURL('image/png');
- $.ajax({
- url: '上传地址', // 要上传的地址
- type: 'post',
- data: {
- 'imgData': photo
- },
- dataType: 'json',
- success: function (data) {
- if (data.status == 0) {
- // 将上传的头像的地址填入,为保证不载入缓存加个随机数
- $('.user-photo').attr('src', '头像地址?t=' + Math.random());
- $('#changeModal').modal('hide');
- } else {
- alert(data.info);
- }
- }
- });
- }
后台中,Java的主要代码如下:(使用了jdk8的Base64,,如果是低版本请自行替换)
- /**
- * 将Base64位编码的图片进行解码,并保存到指定目录
- */
- public static void decodeBase64DataURLToImage(String dataURL, String path, String imgName) throws IOException {
- // 将dataURL开头的非base64字符删除
- String base64 = dataURL.substring(dataURL.indexOf(",") + 1);
- FileOutputStream write = new FileOutputStream(new File(path + imgName));
- byte[] decoderBytes = Base64.getDecoder().decode(base64);
- write.write(decoderBytes);
- write.close();
- }
【jQuery插件分享】Cropper——一个简单方便的图片裁剪插件的更多相关文章
- Cropper – 简单的 jQuery 图片裁剪插件
Cropper 是一个简单的 jQuery 图像裁剪插件.它支持选项,方法,事件,触摸(移动),缩放,旋转.输出的裁剪数据基于原始图像大小,这样你就可以用它们来直接裁剪图像. 如果你尝试裁剪跨域图像, ...
- Croppic – 免费开源的 jQuery 图片裁剪插件
Croppic 这款开源的 jQuery 图片裁剪插件能够满足网站开发人员各种不同的使用需要.只需要简单的上传图片,就可以实现你想要的图像缩放和裁剪功能.因为使用了 HTML5 FormData 对 ...
- 5 款最新的 jQuery 图片裁剪插件
这篇文章主要介绍最新的 5 款 jQuery 图片裁剪插件,可以帮助你轻松的实现你网站需要的图像裁剪功能. Cropit Cropit 是一个 jQuery 插件,支持图像裁剪和缩放功能.Cropit ...
- jQuery 图片裁剪插件 Jcrop
Jcrop是一个jQuery图片裁剪插件,它能为你的WEB应用程序快速简单地提供图片裁剪的功能.特点如下: 对所有图片均unobtrusively(无侵入的,保持DOM简洁) 支持宽高比例锁定 支持 ...
- 基于jQuery功能非常强大的图片裁剪插件
今天我们要来介绍一款基于jQuery功能非常强大的图片裁剪插件,这款jQuery图片裁剪插件可以选择裁剪框的尺寸比例,可以设置高宽尺寸,同时可以设置图片翻转角度,当然也支持图片的缩放,裁剪框也可以用鼠 ...
- 制作一个简单的WPF图片浏览器
原文:制作一个简单的WPF图片浏览器 注:本例选自MSDN样例,并略有改动.先看效果: 这里实现了以下几个功能:1. 对指定文件夹下所有JPG文件进行预览2. 对选定图片进行旋转3. 对选定图片 ...
- 开源JS图片裁剪插件
开源JS图片裁剪插件 一.总结 一句话总结: 要用点赞最高的插件,这样适用性最好,效果最好,出问题的概率也最低,这里电脑端和手机端都可以用的建议用 cropper.js 二.5款好用的开源JS图片裁剪 ...
- 头像截图上传三种方式之一(一个简单易用的flash插件)(asp.net版本)
flash中有版权声明,不适合商业开发.这是官网地址:http://www.hdfu.net/ 本文参考了http://blog.csdn.net/yafei450225664/article/det ...
- 【UI插件】开发一个简单日历插件(上)
前言 最近开始整理我们的单页应用框架了,虽然可能比不上MVVM模式的开发效率,也可能没有Backbone框架模块清晰,但是好歹也是自己开发出来 而且也用于了这么多频道的东西,如果没有总结,没有整理,没 ...
随机推荐
- Angular 4.x 修仙之路
参考:https://segmentfault.com/a/1190000008754631 一个Angular4的博客教程目录
- 值类型的TryParse
值类型(Struct(如:DateTime).基本类型(如:double).枚举类型)的TryParse方法,通常可使用该方法将“字符串”转换为当前类型,并out出.比如:日期格式的字符串 转换为 ...
- JavaScript 打印Div内容
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Untitled Page& ...
- word2016_统计字数
统计字数 审阅->字数统计
- proxy-target-class 作用
该属性值默认为false,表示使用JDK动态代理织入增强;当值为true时,表示使用CGLib动态代理织入增强;但是,即使设置为false,如果目标类没有生命接口, 则Spring将自动使用CGLib ...
- 进程上下文频繁切换导致load average过高
一.问题现象 现网有两台虚拟机主机95%的cpu处于idle状态,内存使用率也不是特别高,而主机的load average达到了40多. 二.问题分析 先在主机上通过top.free.ps.iosta ...
- 在 Bash on Ubuntu 上安装Nginx
前言 Win10 上的 Bash on Ubuntu 是个很好用的玩具,让windows开发环境下的人能无缝操练Linux,但是涉及到网络部分还是有很多要该进的地方,比如Nginx的安装就遇到了问题. ...
- Git 分布式版本控制的常见命令
Git 的作用: (1)方便多人协同开发; (2)方便版本控制 Git 分布式版本控制的主要区域及命令图,下面会详细讲解: 创建项目并将切换至项目目录下 1. 创建本地仓库: git init ...
- 随手写的一个检测php连接mysql的小脚本
最近偶然接触到一点点的php开发,要用到mysql数据库,由于mysql和php版本的关系,php5里面连接函数有mysql_connect(),mysqli_connect()两种,php7中又使用 ...
- URL中不应出现汉字
浏览器会在跳转时,先将汉字编译成 Unicode,然后跳转,导致hash值改变两次,相当于history 中 加入了两次URL