当前位置:   article > 正文

上传裁剪头像(Jcrop)_头像裁剪上传功能实现

头像裁剪上传功能实现

上传裁剪头像(Jcrop)

                                        -- by Stephen
  • 1

2016/1/24 20:17:21


总体思路:用户点击选择头像按钮,选好图片后jcrop所在的div以遮罩层的形式显示,此时异步更新图片的src,即已经在服务器中将该图片保存了。返回给js图片的绝对路径和图片名称。用户点击保存头像按钮,向服务器传递图片名称和裁剪系数,异步回调得到裁剪结果,更新页面。


第一步:引入 jcrop 的 js 和 css 文件
        这里使用了集成好的 basic.js 和 basic.css 和 html,代码可以去 github 上下载(下载地址:https://github.com/Stephen-LG/JcropDemo.git

第二步:解决 input file 样式不好看的问题
        将input file控件的display属性设成none,用另一个input button控件来间接控制input file控件(οnclick=”head_img.click()”,其中head_img为input file的id)。这样将input button控件设置成想要的样式即可

第三步:解决用户上传图片后异步更新jcrop插件中的图片src
        这肯定需要ajax异步请求才能完成,我使用ajaxFileUpload插件来完成这个功能。但是因为这个插件很早就不再更新了,在使用过程中需要注意几点:
1. 在使用时会提示handleError不是一个function,我们在ajaxfileupload.js文件中添加如下代码:

handleError: function( s, xhr, status, e ) {
    // If a local callback was specified, fire it
    if ( s.error ) { 
        s.error.call( s.context || s, xhr, status, e ); 
    }
    // Fire the global callback 
    if ( s.global ) { 
        (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] ); 
    } 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  1. 在服务器返回数据后,该插件会自动在数据外面包裹上pre标签,因为它使用eval函数,解决方式如下:
            在uploadHttpData函数中的
if ( type == "json" )
    eval( "data = " + data );
  • 1
  • 2

        改成

if ( type == "json" )
    data = jQuery.parseJSON(jQuery(data).text());
  • 1
  • 2
  1. 在回调函数中更新img的src后,插件获取到新图片的长宽一直是上一个。原因应该是在于,动态更改src以后,图片还没有下载完成,这个时候图片还没有被替换。解决方式如下:
$("#img").on("load",function(){
    //这里添加你的函数就OK
});
  • 1
  • 2
  • 3
  1. 用onchage函数监听input file控件只会触发一次。解决方式如下:
$(document).delegate('input[name=head_img]', 'change', function() {});
  • 1
  1. 在选择过一次图片后在选择一次,这时img标签的width和height不会改变,而是图片拉伸了,解决方式如下:
            将img标签移除再重新创建即可:
$('#origi-img').remove();
$('.jcrop_w').append("<img src='' id='origi-img' />");
  • 1
  • 2

第四步:解决Jcrop的裁剪框只在缩略过的图片内部进行移动和裁剪
        这个问题想了不少时间,最后用了比较笨的方法,在用户选择了图片后,用一个函数计算出缩略后的图片宽高,在获取Jcrop实例后用$(‘.jcrop-holder’).css({left:holderW,top:holderH});

第五步:解决向服务器传递裁剪参数

$('#target').Jcrop({
    onChange: showPreview,
    onSelect: showPreview,
    // ...其他options
});
  • 1
  • 2
  • 3
  • 4
  • 5

        在这两个回调函数中及时对裁剪系数进行更新,保存在html页面中的input hidden中,一共有六个系数

$('#x1').val(c.x); // 选择框最左上角的x坐标值
$('#y1').val(c.y); // 选择框最左上角的y坐标值
$('#x2').val(c.x2); // 选择框最右下角的x坐标值
$('#y2').val(c.y2); // 选择框最右下角的y坐标值
$('#w').val(c.w); // 选择框的宽度
$('#h').val(c.h); // 选择框的高度
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

        那么问题来了。。。在用户选择图片后向服务器发送的是一张正常大小的图片,然后在jcrop页面中显示的是缩略过的图片,裁剪框是在缩略过的图片上进行的裁剪,因此还得向服务器发送一个缩略比例,因此在cutImage函数中将缩略比例存储在input hidden中

第六步:解决服务器裁剪图片
        我这里使用的是php语言,因此用了php的GD库函数配合从前端获得传递过来的起始坐标(x,y)以及裁剪的宽高和缩略比例较为轻松的实现了,这里不细述了,有兴趣看源代码
示例图

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/565249
推荐阅读
相关标签
  

闽ICP备14008679号