從微信圖片選擇接口到七牛雲圖牀(java+js)

主要功能:調用微信圖片選擇接口,用戶確定之後將圖片上傳到七牛雲,然後將返回的圖片地址保存到本地數據庫對應字段

踩的坑

  • 微信JSDDK 1.1.0和1.2.0的差異
  • 安卓手機和IOS的差異

主要表現在wx.chooseImagewx.uploadImage,還有選擇圖片之後獲取到如: wxlocalresource://imageid123456789987654321 這樣的圖片地址,IOS無法預覽,或者wx.uploadImage接口在IOS上只能上傳一張圖片。

微信官方文檔

七牛雲SDK

七牛雲fetch接口

實現的思路

  • 通過wx.chooseImage接口讓用戶選擇圖片,選擇之後生成預覽
  • 通過wx.uploadImage接口將圖片上傳到微信服務器做臨時素材
  • 通過七牛雲fetch接口去下載微信服務器上的圖片

代碼實現

引入權限驗證

// config權限驗證
function wxconfig(url){
    $.post('/weixin/configvalid', {'url':url.toString()}, function(data){
        wx.config({
            debug: false,
            appId: data.appId,
            timestamp: data.timestamp,
            nonceStr: data.nonceStr,
            signature: data.signature,
           /* jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage']*/
            jsApiList: [
                        'checkJsApi',
                        'onMenuShareTimeline',
                        'onMenuShareAppMessage',
                        'onMenuShareQQ',
                        'onMenuShareWeibo',
                        'onMenuShareQZone',
                        'hideMenuItems',
                        'showMenuItems',
                        'hideAllNonBaseMenuItem',
                        'showAllNonBaseMenuItem',
                        'translateVoice',
                        'startRecord',
                        'stopRecord',
                        'onVoiceRecordEnd',
                        'playVoice',
                        'onVoicePlayEnd',
                        'pauseVoice',
                        'stopVoice',
                        'uploadVoice',
                        'downloadVoice',
                        'chooseImage',
                        'previewImage',
                        'uploadImage',
                        'downloadImage',
                        'getNetworkType',
                        'openLocation',
                        'getLocation',
                        'hideOptionMenu',
                        'showOptionMenu',
                        'closeWindow',
                        'scanQRCode',
                        'chooseWXPay',
                        'openProductSpecificView',
                        'addCard',
                        'chooseCard',
                        'openCard',
                        'openAddress',
                        'getLocalImgData'
                    ]
        });
    });
}

導包 (這裏我們用微信JSJDK 1.2.0)

<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>

選擇圖片,上傳圖片參考官方demo(我是遇到了一大籮筐問題之後纔看到這個救命的demo)

// 5 圖片接口
  // 5.1 拍照、本地選圖
  var images = {
    localId: [],
    serverId: []
  };
  document.querySelector('#chooseImage').onclick = function () {
    wx.chooseImage({
      success: function (res) {
        images.localId = res.localIds;
        alert('已選擇 ' + res.localIds.length + ' 張圖片');
      }
    });
  };
// 5.3 上傳圖片
  document.querySelector('#uploadImage').onclick = function () {
    if (images.localId.length == 0) {
      alert('請先使用 chooseImage 接口選擇圖片');
      return;
    }
    var i = 0, length = images.localId.length;
    images.serverId = [];
    function upload() {
      wx.uploadImage({
        localId: images.localId[i],
        success: function (res) {
          i++;
          alert('已上傳:' + i + '/' + length);
          images.serverId.push(res.serverId);
          if (i < length) {
            upload();
          }
        },
        fail: function (res) {
          alert(JSON.stringify(res));
        }
      });
    }
    upload();
  };

這個上傳的例子可以解決圖片只能上傳一張的問題,我們就基於這個例子改進我們的代碼。

wxconfig(window.location);

// 5 圖片接口
// 5.1 拍照、本地選圖
var images = {
  localId: [],
  serverId: []
};
var arrayImgs = new Array();
document.querySelector('#uploaderInput').onclick = function () {
  wx.chooseImage({
    success: function (res) {
      images.localId = res.localIds;
      //生成預覽 區分一下ios跟其他系統
      var localIds  = res.localIds;
      if(window.__wxjs_is_wkwebview){
        //alert(localIds[0])

        for (id in localIds) {
          wx.getLocalImgData({
            localId: localIds[id],
            success: function (res) {
              var localData = res.localData;
              localData = localData.replace('jgp', 'jpeg');
              var tmpl = '<img class="weui-uploader__file weui-uploader__file_status" src="'+localData+'" data-src="'+localIds[id]+'"/>';
              $("#uploaderFiles").append(tmpl)
            },
            fail:function(res){
              alert(res.errMsg);
            }
          });
        }
      }else{
        //遍歷數組
        for (id in localIds){   
          var tmpl = '<img class="weui-uploader__file weui-uploader__file_status" src="#url#" data-src="#url#"/>';
          $("#uploaderFiles").append($(tmpl.replace(/#url#/ig, localIds[id])));

        } 
      }
    }
  });
};
 // 5.3 上傳圖片
document.querySelector('#upload_img1').onclick = function () {
  if (images.localId.length == 0) {
    alert('請先選擇圖片');
    return;
  }
  var i = 0, length = images.localId.length;
  images.serverId = [];
  function upload() {
    wx.uploadImage({
      localId: images.localId[i],
      success: function (res) {
        arrayImgs[i] = res.serverId
        console.log(typeof(arrayImgs))
        i++;
        //alert('已上傳:' + i + '/' + length);
        images.serverId.push(res.serverId);
        if (i < length) {
          upload();
        }else{
          // 循環結束
          topost(arrayImgs)
        }
      },
      fail: function (res) {
        alert(JSON.stringify(res));
      }
    });
  }
  upload();
};

最後向後臺服務器發送請求

 function topost(obj){
   var resImgurl = obj.join(",")
   $.ajax({
     url: '/qiniuImg',
     data: {
       "resImgurl":resImgurl,
       "content":"測試"
     },
     type: 'post',
     dataType: 'json',
     cache: false,
     success: function(data){
       console.log(data)
       if(data.re){
         console.log("成功寫入數據庫,進行頁面跳轉!")
         alert(data.msg)
         location.replace('/index');
       }else{
         alert(data.msg)
       }
     }
   }); 
 }

後臺獲取圖片

String resImgurl = getPara("resImgurl");

// 獲取圖片信息
List<String> imgurl =  new ArrayList<String>();
int i = 0;int j = 1;

String[] media_list = resImgurl.split(",");

for (String media_id : media_list) {
  String key = QianNiuUpload.fetchTmpFile(media_id, "");
  String url = QianNiuUpload.domain + key;
  imgurl.add(url);
}

.... 
將圖片的url 寫入數據庫

QianNiuUpload.java

public class QianNiuUpload {
    //設置好賬號的ACCESS_KEY和SECRET_KEY
    public static String ACCESS_KEY = "xxxxxx";
    public static String SECRET_KEY = "xxxxxx";
    //要上傳的空間
    public static String bucketname = "xxxxxx";

    public static String domain = "http://xxxxxxx.com/"; // 空間的域名

    //上傳到七牛後保存的文件名
    public static String key = "隨意,這個例子我們沒用到";
    //上傳文件的路徑
    public static String FilePath = "隨意,這個例子我們沒用到";

    //密鑰配置
    public static Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);

    //第二種方式: 自動識別要上傳的空間(bucket)的存儲區域是華東、華北、華南。
    public static Zone z = Zone.autoZone();
    public static Configuration c = new Configuration(z);

    //創建上傳對象
    private static UploadManager uploadManager = new UploadManager(c);

    //簡單上傳,使用默認策略,只需要設置上傳的空間名就可以了
    public static String getUpToken() {
        return auth.uploadToken(bucketname);
    }

    public static void upload() throws IOException {
        try {
            //調用put方法上傳
            Response res = uploadManager.put(FilePath, key, getUpToken());
            //打印返回的信息
            System.out.println(res.bodyString());
        } catch (QiniuException e) {
            Response r = e.response;
            // 請求失敗時打印的異常的信息
            System.out.println(r.toString());
            try {
                //響應的文本信息
                System.out.println(r.bodyString());
            } catch (QiniuException e1) {
                //ignore
            }
        }
    }

    //定義兩個成員變量常量
    //獲取臨時素材(視頻不能使用https協議)
    public static final String GET_TMP_MATERIAL = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s";
    //獲取臨時素材(視頻)
    public static final String GET_TMP_MATERIAL_VIDEO = "http://api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s";

     //獲取微信服務器中生成的媒體文件
     //由於視頻使用的是http協議,而圖片、語音使用http協議,故此處需要傳遞media_id和type

    public static String fetchTmpFile(String media_id, String type){
           try {
                String token = AccessTokenApi.getAccessToken().getAccessToken();
                String url = null;

                //視頻是http協議
                if("video".equalsIgnoreCase(type)){
                 url = String.format(GET_TMP_MATERIAL_VIDEO, token, media_id);
                }else{
                 url = String.format(GET_TMP_MATERIAL, token, media_id);;
                }
                URL Nurl = new URL(url);
                //構造一個帶指定Zone對象的配置類
                Configuration cfg = new Configuration(Zone.autoZone());  

                Auth me = Auth.create(ACCESS_KEY,SECRET_KEY);
                BucketManager bucketManager = new BucketManager(me, cfg);
               // bucketManager.fetch("外源圖片地址", "要上傳的七牛目標資源文件夾", "文件名");
                // 這邊的文件名如果省略 七牛會隨機給個名字
                FetchRet fetchRet = bucketManager.fetch(url,bucketname);

                //System.out.println(fetchRet.hash);
                System.out.println(fetchRet.key);
                //System.out.println(fetchRet.mimeType);
                //System.out.println(fetchRet.fsize);
                return fetchRet.key;
              } catch (Exception e) {
               e.printStackTrace();
              }
        return null;
    }  
}

java 後臺七牛返回的上傳後的文件名

七牛雲存儲空間可以看到圖片已經成功上傳了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章