如何在微信公衆號開發中實現圖片裁剪

接觸微信公衆號開發已經有一段時間了,發現其實和網頁開發差很少,可是由於瀏覽器的不一樣,本身也碰過一些坑,其中就有怎麼實現圖片裁剪功能。javascript

一開始我是用PC端的思路去作的,首先在本地獲取圖片路徑,而後在網頁中顯示,最後在本地裁剪,而後把裁剪好的圖片轉換成base64數據,上傳到服務器。作完以後,我爲css

了測試,我是直接把圖片路徑寫到img裏面的,省略了選擇圖片這個步驟,最後在微信測試是經過的。可是我把選擇圖片的步驟加上以後,就出了問題。html

我是用cropper框架(不支持jq的版本)實現的,由於這個框架支持移動端操做的,下面我就把這個過程當中出現的問題寫一下。java

<!DOCTYPE html>  
    <html>  
        <head>  
            <meta charset="utf-8">  
            <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />  
            <title></title>  
            <link rel="stylesheet" href="css/cropper.css" />  
      
            <style>  
                .img-content img {  
                    max-width: 100%;  
                }  
            </style>  
      
        </head>  
      
        <body>  
            <div class="img-content">  
                <!--src是微信的圖片ID,能夠直接在img裏面顯示-->  
                <img id="photo" src="wxLocalResource://488970461173136">  
            </div>  
      
            <button id="confirm">肯定</button>  
      
        </body>  
        <script type="text/javascript" src="js/cropper.js"></script>  
        <script>  
            var photo = document.getElementById("photo");  
            var cropper = new Cropper(photo, {  
                aspectRatio: 1,  
            });  
          
            document.getElementById('confirm').addEventListener('click', function() {  
                var canvas=cropper.getCanvasData();  
                var base64Data=canvas.toDataURL("image/jpeg",1);  
                alert(base64Data);  
            });  
        </script>  
      
    </html>

 

上面那段代碼在微信端運行的時候,js部分會報錯git

1,在cropper初始化的時候會報錯,報XMLHtmlRequest DOM 18的錯誤github

2,在獲取圖片數據 toDataURL的時候會報錯,報undefined function的錯誤ajax

 

其實這兩個問題我以爲應該是微信瀏覽器的問題。因此我用了另一種方式實現。仍是使用cropper裁剪插件json

一、把選擇到的圖片ID上傳到微信的服務器,獲取serverId(微信服務器的圖片ID)canvas

二、修改cropper的js,使得cropper在初始化的時候不報錯api

三、在本地裁剪,可是不獲取裁剪後的base64數據,獲取裁剪的區域參數,把serverId和那些參數發送到本身的服務器

四、從微信服務器下載圖片到本身的服務器,裁剪,壓縮,保存到本身的服務器。

 

下面我把全部的步驟都寫出來

 

首先要使用微信js-sdk獲取圖片的ID,圖片ID就是圖片的路徑,這個ID能夠直接在img標籤顯示。

1,初始化微信js-sdk

2,調用微信選擇圖片的js

3,從返回的數據中獲取圖片ID

爲了方便,我就寫js部分

//微信初始化  
    wx.config({  
        debug: false,  
        appId: '${wx_app_id}',  
        timestamp: ${wx_js_timestamp},  
        nonceStr: '${wx_js_noncestr}',  
        signature: '${wx_js_mydata}',  
        jsApiList: [  
            'chooseImage',  
            'uploadImage',  
        ]  
    });  
      
    //微信初始化成功  
    wx.ready(function(){  
        document.getElementById("picture").addEventListener('click', function(){  
            wx.chooseImage({  
                count: 1,   //一次性能夠選擇多少張圖片,默認9  
                sizeType: ['original','compressed'],//圖片的類型:原圖,壓縮圖  
                sourceType: ['album','camera'],  //圖片來源:相冊,拍照  
                success: function(localRes){  
                    var localIdVal = localRes.localIds[0];  //本地第一張圖片ID  
                    //獲取到圖片後,上傳的服務器,獲得服務器的ID  
                    wx.uploadImage({  
                        localId: localIdVal,   //本地圖片ID  
                        isShowProgressTips: 1, //顯示加載圈  
                        success: function (serverRes) {  
                            var serverIdVal=serverRes.serverId;  
                            window.location.href="mine/photocrop?localId="+localIdVal+"&serverId="+serverIdVal,  
                        },  
                        fail: function (res) {  
                            mui.alert(JSON.stringify(res));  
                        }  
                    });  
                },  
                cancel: function () {  
                    //  
                }  
            });  
        });  
    });  
    //微信初始化失敗  
    wx.error(function(res){  
        document.getElementById("picture").addEventListener('tap', function(){  
            mui.alert("微信初始化失敗");  
        });  
    });

 

首先要初始化微信,調用wx.config的方法,若是初始化成功,那麼wx.ready就會調用,若是失敗,那麼就調用wx.error方法

初始化成功以後,給按鈕添加點擊的方法,這樣點擊的時候,就會調用wx.chooseImage的方法,在瀏覽器就會彈出選擇圖片的彈窗,選擇圖片以後,能夠獲取本地的圖片ID,而後上傳圖片到服務器,能夠獲取微信服務器的圖片ID。

如今說一下本地圖片ID和微信服務器圖片ID的用途,本地圖片ID要用於裁剪的,服務器的圖片ID是用於下載的。

下面修改cropper框架,其實初始化報錯實際上是由於cropper會去下載本地的圖片,因此咱們那段代碼刪掉

打開cropper.js,找到854行,把這段代碼刪掉,添加一句__this.clone(),這一句必須的。

其實咱們還須要禁掉滑輪縮放和手指縮放的功能,由於若是不由掉,那麼裁剪框的區域就不正確了,把下面的代碼註釋掉

滑輪縮放的代碼

手指縮放的代碼

好了,cropper已經修改完了,記得要引用修改後的cropper.js

下面裁剪圖片了

<!DOCTYPE html>  
    <html>  
      
        <head>  
            <title>裁剪</title>  
            <link rel="stylesheet" href="sources/css/cropper.css" />  
            <style>  
                .img-content img {  
                    max-width: 100%;  
                }  
            </style>  
        </head>  
      
        <body>  
            <div>  
                <div class="img-content">  
                    <img id="photo" src="${localId}">  
                </div>  
      
                <button id="confirm">  
                    肯定  
                </button>  
            </div>  
            <script src="sources/js/cropper.js"></script>  
            <script type="text/javascript" charset="utf-8">  
                mui.ready(function() {  
                    var photo = document.getElementById("photo");  
                    var cropper = new Cropper(photo, {  
                        aspectRatio: 1,  
                    });  
      
                    var btnConfirm = document.getElementById("confirm");  
                    btnConfirm.addEventListener("tap", function() {  
                        btnConfirm.innerText = "正在處理...";  
                        btnConfirm.disabled = true;  
      
                        var canvasData = cropper.getCanvasData();  
                        var cropBoxData = cropper.getCropBoxData();  
      
                        //要根據圖片的縮放計算實際的大小  
                        var scale = canvasData.naturalWidth / canvasData.width;  
                        var topVal = (cropBoxData.top - canvasData.top) * scale;  
                        var leftVal = cropBoxData.left * scale;  
                        var widthVal = cropBoxData.width * scale;  
      
                        mui.ajax('mine/uploadPhoto', {  
                            data: {  
                                serverId: '${serverId}',  
                                top: topVal,  
                                left: leftVal,  
                                width: widthVal  
                            },  
                            type: 'post',  
                            dataType: 'json',  
                            success: function(data) {  
                                mui.alert(data.msg, function() {  
                                    if (!data.success) {  
                                        btnConfirm.innerText = "肯定";  
                                        btnConfirm.disabled = false;  
                                    }  
                                });  
                            },  
                            error: function(xhr, type, errorThrown) {  
                                mui.alert(type);  
                                btnConfirm.innerText = "肯定";  
                                btnConfirm.disabled = false;  
                            }  
                        });  
                    });  
                });  
            </script>  
        </body>  
      
    </html>

 

首先用本地的圖片ID顯示,而後裁剪,獲取裁剪的參數,而後把微信服務器的圖片ID也上傳到本身的服務器,而後在本身的服務器處理

下面這段代碼包括從微信服務器下載圖片,裁剪,壓縮,保存到服務器

public static final String downloadUserPhoto(String serverId, int left, int top, int width) {  
            String path = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=fasdfsaffasdfa&media_id=" + serverId;  
            HttpURLConnection con = null;  
            FileOutputStream fos = null;  
            try {  
                URL url = new URL(path);  
                con = (HttpURLConnection) url.openConnection();  
                con.setConnectTimeout(5000);  
                con.connect();  
                if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {  
                    String type = con.getHeaderField("Content-Type");  
                    //判斷是否是圖片類型  
                    if (type != null && type.contains("image")) {  
                        String ext = type.substring(type.lastIndexOf("/") + 1);  
                        String filename = UUID.randomUUID().toString() + "." + ext;  
                        File file = new File("download/images/",filename);  
      
                        if (!file.getParentFile().exists()) {  
                            file.getParentFile().mkdirs();  
                        }  
      
                        BufferedImage bufImg = ImageIO.read(con.getInputStream());  
                        bufImg = bufImg.getSubimage(left, top, width, width);  
                        //壓縮圖片,若是圖片的像素寬度超過160  
                        if (width > 160) {  
                            float wr = 160 * 1f / bufImg.getWidth();  
                            AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(wr, wr), null);  
                            bufImg = ato.filter(bufImg, null);  
                        }  
      
                        fos = new FileOutputStream(file);  
                        ImageIO.write(bufImg, ext, fos);  
                        String filepath = pathdir + "/" + filename;  
                        return filepath;  
                    }  
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
                try {  
                    if (fos != null) {  
                        fos.close();  
                    }  
                    if (con != null) {  
                        con.disconnect();  
                    }  
                } catch (Exception el) {  
                    el.printStackTrace();  
                }  
            }  
            return null;  
        }

 

其實最大的區別就是把本地裁剪移到服務器裁剪。沒有demo,這些代碼是從一個項目複製過來的

相關文章
相關標籤/搜索