敲代码敲到怀疑人生(html2canvas,上传图片,服务器读取本地图片)

  2017已经接近尾声了,可是我却怀疑人生了。。。

  (给自己一个warning的颜色,以作警醒吧)

 

最近做了一个邀请函的项目,邀请函无非就是向受邀者展示此次活动的时间、地点、活动的流程安排,最后想来的人再报个名登记一下。

这倒没什么,重点是它后续还有一个根据用户填写的信息,有个生成胸卡的功能。

1.上传图片与图片裁剪

胸卡当然是要上传照片的。上传照片的插件倒比比皆是,可是能很好地兼容Android和Ios系统的并且具有裁剪功能的就很少了。

最后我决定直接调微信的上传图片图片接口。过程如下:

  1.引入js文件 http://res.wx.qq.com/open/js/jweixin-1.2.0.js

 

 

  2. 你的ajax请求的data里需要有这一项  jsApiList:'["chooseImage","uploadImage"]'

 

  3.通过config接口注入权限验证配置 写在ajax请求成功的回调里)

 

success:function(response){
  var _response = response.data
  var _appId =_response.appId
  var _timestamp =_response.timestamp
  var _nonceStr =_response.nonceStr
  var _signature =_response.signature
  wx.config({
    debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId:_appId, // 必填,公众号的唯一标识
    timestamp:_timestamp, // 必填,生成签名的时间戳
    nonceStr: _nonceStr, // 必填,生成签名的随机串
    signature:_signature, // 必填,签名,见附录1
    jsApiList: [
      'chooseImage',
      'uploadImage'
    ] // 必填,需要使用的JS接口列表
  });
}

 

 

##拍照或从手机相册中选图接口

 

wx.chooseImage({
  count: 1, // 默认9
  sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
  sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
  success: function (res) {
    var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
  }
});

注意:res.localIds是一个数组,数组长度等于你指定的count的值,也就是当count为1时,你想拿到src需要通过res.localIds[0]

##上传图片接口

wx.uploadImage({
  localId: '', // 需要上传的图片的本地ID,由chooseImage接口获得
  isShowProgressTips: 1, // 默认为1,显示进度提示
  success: function (res) {
    var serverId = res.serverId; // 返回图片的服务器端ID
  }
});

上传完成之后页面相关区域绑定上localId就可以拿到相关图片了;

 

然而微信上传图片时的裁剪功能是好多人不知道滴,有些尴尬了,最后修改了图片上传的区域,宽高比是1:1.333,而不是(9:16);

在这儿再推荐一款图片裁剪的插件吧,轻量级的,并且很好用  PhotoClip.js(如果无法打开,请FQ,或者自行下载体验)

(http://htmlpreview.github.io/?https://github.com/baijunjie/PhotoClip.js/blob/master/demo/index.html)

 

2.本地图片上传到服务器

上传图片,裁剪图片并不是最让人恼火的。

把html转成canvas,再把生成的本地图片上传到服务器是一个难点(

服务器读取本地图片,听后台人员说必须通过二进制流的形式),于是开始了漫长的资料查阅……

 

html2canvas(document.getElementById('xcard'), {
  onrendered: function(canvas) {
    document.body.appendChild(canvas);
    var blob = getBlob(canvas);
    var oMyForm = new FormData();
    var fileName = mobile+ '.jpg'
    oMyForm.append("uploadFile", blob);
    oMyForm.append("fileName", fileName);
    oMyForm.append("fileType", 'image');
    $.ajax({
      type: "POST",
      url: BasicPath.URL + InterFaceJson.uploadSingleFile, //后台接口路径
      data: oMyForm,
      contentType: false,
      processData: false,
      cache: false, 
      success:function(res){

      }
    });
  }
});

 

 

function getBlob(canvas){ //获取blob对象
  var data = canvas.toDataURL("image/jpeg", 1);
  data = data.split(',')[1];
  data = window.atob(data);
  var ia = new Uint8Array(data.length);
  for(var i = 0; i < data.length; i++) {
    ia[i] = data.charCodeAt(i);
  }
  return new Blob([ia], {
    type: "image/jpeg"
  });
}

 

代码的实现机制到现在我还是不太懂,简单介绍一下吧。

blob是一个装载二进制流的容器(服务器读取时需要读二进制流);

前后台交互不能使用jq的ajax方式,而是使用表单的提交方式。

也就是上面两段代码了。

 

3.html2canvas 也是一个巨坑

html2canvas官网是及其简洁的。然而使用过程中,有太多的css样式它是不认识的,因此html呈现的代码和canvas生成的图片往往会有出入,这个时候不要着急,并且需要注意它在Android和ios上的呈现区别。不要高兴的太早,我们需要细心与耐心。

 

posted @ 2017-12-15 11:08  虫之Blog  阅读(3213)  评论(0编辑  收藏  举报