Rails 用户头像 (Avatar Upload) 剪切上传方案整合

kooglezhang · 2016年08月01日 · 最后由 thinkphper 回复于 2016年08月22日 · 5208 次阅读

在开发个人网站的时候,遇到一个问题,就是用上传头像剪切后再重新上传,用户只需要提供图片,而不用手动在自己电脑上用其他的软件作为预处理后再点击上传, 可以随意剪切成自己满意的大小

前端图片 Js 剪切使用 Cropbox

图片剪切部分 Js

<script type="text/javascript">
  $(window).load(function() {
    var options =
    {
      thumbBox: '.thumbBox',
      spinner: '.spinner',
      // imgSrc: 'images/avatar.png'
    }
    var cropper = $('.imageBox').cropbox(options);
    $('#upload-file').on('change', function(){
      var reader = new FileReader();
      reader.onload = function(e) {
        options.imgSrc = e.target.result;
        cropper = $('.imageBox').cropbox(options);
      }
      reader.readAsDataURL(this.files[0]);
      this.files = [];
    })
    $('#btnCrop').on('click', function(){
      var img = cropper.getDataURL();
      $('.cropped').attr('style','display:block');
      $('.cropped').html('');
      $('.cropped').append('<br><img src="'+img+'" align="absmiddle" class="tu_yuan">');
      $('.cropped').append('<img src="'+img+'" align="absmiddle" class="tu_fang">');
      $('#data').val(img);
      $('#tijiao').removeAttr('style');
    })
    $('#btnZoomIn').on('click', function(){
        cropper.zoomIn();
    })
    $('#btnZoomOut').on('click', function(){
        cropper.zoomOut();
    })
  });
  $(document).on('page:fetch',   function() { NProgress.start(); });
  $(document).on('page:change',  function() { NProgress.done(); });
</script>

重新剪切后的图片数据需要在后端作为编码处理

def create_avatar
  file = Base64.decode64(params[:avatar]['data:image/png;base64,'.length .. -1])
  file_name = "img_#{Cattle.rand_string_name(20)}.png"
  file_path = "#{Rails.root}/public/uploads/#{file_name}"
  File.open(file_path,'wb+') do |item|
    item.write(file)
  end
  current_user.avatar = Cattle.upload_yun(file_name,file_path)
end

将剪切后的图片缓存到系统,然后将文件上传至 CDN,保存返回的 url 链接 下图是图片剪切后的效果

想体验的朋友可以戳 http://koogle.cc 到个人用户中心

能解释下后端裁剪的意思么?或者给个案例托管的 url 我自己下来看,谢谢。

#1 楼 @yan1667 就是用 Cropbox 在页面将图片剪切好,这个时候剪切后的图片是一长串的图片编码,在后端需要将这些编码写到文件 png 文件里,这个时候才算成功剪切,然后将它存储到你的云端即可

#2 楼 @kooglezhang 前面我都懂什么意思 def create_avatar file = Base64.decode64(params[:avatar]['data:image/png;base64,'.length .. -1]) file_name = "img_#{Cattle.rand_string_name(20)}.png" file_path = "#{Rails.root}/public/uploads/#{file_name}" File.open(file_path,'wb+') do |item| item.write(file) end current_user.avatar = Cattle.upload_yun(file_name,file_path) end 这段代码什么意思,就是不知道如何将 base64 位存进去

#3 楼 @yan1667

def create_avatar
    file = Base64.decode64(params[:avatar]['data:image/png;base64,'.length .. -1])   # 将 Base64 编码的参数用 Base64 解码,得到数据的二进制表示,也就是图片本身的二进制数据
    file_name = "img_#{Cattle.rand_string_name(20)}.png" # 声明一个随机的文件名
    file_path = "#{Rails.root}/public/uploads/#{file_name}"  # 确定文件保存路径
    File.open(file_path,'wb+') do |item|  # 跟聚文件路径创建新文件
      item.write(file)   # 将前面的二进制数据写到文件里,这个时候的文件就是一个完整的图片文件了
    end
    current_user.avatar = Cattle.upload_yun(file_name,file_path)   # 将前面的图片文件与用户记录关联。
  end

代码并不复杂,图片本身就是一个二进制数据的文件而已。上面代码并不是你说的如何存 base64,它是先解码 base64,保存解码后的二进制数据。

#4 楼 @martin91 谢谢,我就在解码这载了。这个插件应该是保存的截取的小图吧

#6 楼 @yan1667 肯定啊。客户端或者浏览器端传什么数据就是保存什么数据。

#4 楼 @martin91 之前的回答有误区,谢谢指正,共同学习

我们后端剪切的做法是记录剪切的图片的四个点的坐标,然后用imagemagick后端剪切

11 楼 已删除
需要 登录 后方可回复, 如果你还没有账号请 注册新账号