如何在微信公众号开发中实现图片裁剪

接触微信公众号开发已经有一段时间了,发现其实和网页开发差很少,可是由于浏览器的不一样,本身也碰过一些坑,其中就有怎么实现图片裁剪功能。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,这些代码是从一个项目复制过来的

相关文章
相关标签/搜索