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

接触微信公众号开发已经有一段时间了,发现其实和网页开发差不多,但是因为浏览器的不同,自己也碰过一些坑,其中就有怎么实现图片裁剪功能。

一开始我是用PC端的思路去做的,首先在本地获取图片路径,然后在网页中显示,最后在本地裁剪,然后把裁剪好的图片转换成base64数据,上传到服务器。做完之后,我为

了测试,我是直接把图片路径写到img里面的,省略了选择图片这个步骤,最后在微信测试是通过的。但是我把选择图片的步骤加上之后,就出了问题。


我是用cropper框架(不支持jq的版本)实现的,因为这个框架支持移动端操作的,下面我就把这个过程中出现的问题写一下。



	
		
		
		
		

		

	

	
		

上面那段代码在微信端运行的时候,js部分会报错

1,在cropper初始化的时候会报错,报XMLHtmlRequest DOM 18的错误

2,在获取图片数据 toDataURL的时候会报错,报undefined function的错误


其实这两个问题我觉得应该是微信浏览器的问题。所以我用了另外一种方式实现。还是使用cropper裁剪插件

1、把选择到的图片ID上传到微信的服务器,获取serverId(微信服务器的图片ID)

2、修改cropper的js,使得cropper在初始化的时候不报错

3、在本地裁剪,但是不获取裁剪后的base64数据,获取裁剪的区域参数,把serverId和那些参数发送到自己的服务器

4、从微信服务器下载图片到自己的服务器,裁剪,压缩,保存到自己的服务器。


下面我把所有的步骤都写出来


首先要使用微信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(),这一句必须的。

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

其实我们还需要禁掉滑轮缩放和手指缩放的功能,因为如果不禁掉,那么裁剪框的区域就不正确了,把下面的代码注释掉

滑轮缩放的代码

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

手指缩放的代码

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

好了,cropper已经修改完了,记得要引用修改后的cropper.js

下面裁剪图片了




	
		裁剪
		
		
	

	
		

首先用本地的图片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,这些代码是从一个项目复制过来的

如果有什么问题,请给我留言




你可能感兴趣的:(如何在微信公众号开发中实现图片裁剪)