JS+VUE realizes image compression, judgment of direction angle, and image rotation processing

The idea to solve this problem is: get the direction angle of the photo, and perform angle rotation correction on the non-horizontal ios photo.

Use exif.js to read the shooting information of the photo, see http://code.ciaoca.com/javascript/exif-js/ for details

<script type="text/javascript" src="js/exif.js" ></script>

 

HTML

<input @change="selectFileImage" class="weui-uploader__input" type="file" accept="image/*" multiple />

JS

/**
 * 选择图片
 */
function selectFileImage(e) {
	let file = e.target.files[0];
	//图片方向角 added by lzk  
	var Orientation = null;
	if (file) {
		console.log("正在上传,请稍后...");
		console.log("size=" + formatSize(file.size));
		var rFilter = /^(image\/jpeg|image\/png)$/i; // 检查图片格式  
		if (!rFilter.test(file.type)) {
			//showMyTips("请选择jpeg、png格式的图片", false);  
			html.showTooltips('请选择jpeg、png格式的图片');
			return;
		}
		// var URL = URL || webkitURL;  
		//获取照片方向角属性,用户旋转控制  
		EXIF.getData(file, function() {
			EXIF.getAllTags(this);
			Orientation = EXIF.getTag(this, 'Orientation');
		});
		var oReader = new FileReader();
		oReader.onload = function(e) {
			var image = new Image();
			image.src = e.target.result;
			image.onload = function() {
				var expectWidth = this.naturalWidth;
				var expectHeight = this.naturalHeight;

				if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) {
					expectWidth = 800;
					expectHeight = expectWidth * this.naturalHeight / this.naturalWidth;
				} else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) {
					expectHeight = 1200;
					expectWidth = expectHeight * this.naturalWidth / this.naturalHeight;
				}
				var canvas = document.createElement("canvas");
				var ctx = canvas.getContext("2d");
				canvas.width = expectWidth;
				canvas.height = expectHeight;
				ctx.drawImage(this, 0, 0, expectWidth, expectHeight);

				var img_size = file.size;
				console.log("img_size=" + img_size);
				let quality = 1;
				if (img_size <= 1024 * 1024) {
					quality = 1.0;
				} else if (img_size <= 2048 * 1024) {
					quality = 0.8;
				} else if (img_size <= 3072 * 1024) {
					quality = 0.7;
				} else if (img_size <= 4096 * 1024) {
					quality = 0.6;
				} else if (img_size <= 5125 * 1024) {
					quality = 0.5;
				} else {
					quality = 0.4;
				}
				console.log("quality=" + quality);
				var base64 = null;
				//修复ios  
				if (navigator.userAgent.match(/iphone/i)) {
					console.log('iphone');
					console.log(expectWidth + ',' + expectHeight);
					console.log(Orientation);
					//如果方向角不为1,都需要进行旋转 added by lzk  
					if (Orientation != "" && Orientation != 1) {
						console.log('旋转处理');
						switch (Orientation) {
							case 6: //需要顺时针(向左)90度旋转  
								console.log('需要顺时针(向左)90度旋转');
								rotateImg(this, 'left', canvas);
								break;
							case 8: //需要逆时针(向右)90度旋转  
								console.log('需要顺时针(向右)90度旋转');
								rotateImg(this, 'right', canvas);
								break;
							case 3: //需要180度旋转  
								console.log('需要180度旋转');
								rotateImg(this, 'right', canvas); //转两次  
								rotateImg(this, 'right', canvas);
								break;
						}
					}
					base64 = canvas.toDataURL("image/jpeg", quality);
				} else if (navigator.userAgent.match(/Android/i)) {
					// 修复android  
					//var encoder = new JPEGEncoder();
					//base64 = encoder.encode(ctx.getImageData(0, 0, expectWidth, expectHeight), 80);

					// base64码
					// var base64 = e.target.result; //或e.target都是一样的

					base64 = canvas.toDataURL("image/jpeg", quality);

				} else {
					console.log(Orientation);
					if (Orientation != "" && Orientation != 1) {
						console.log('旋转处理');
						switch (Orientation) {
							case 6: //需要顺时针(向左)90度旋转  
								console.log('需要顺时针(向左)90度旋转');
								rotateImg(this, 'left', canvas);
								break;
							case 8: //需要逆时针(向右)90度旋转  
								console.log('需要顺时针(向右)90度旋转');
								rotateImg(this, 'right', canvas);
								break;
							case 3: //需要180度旋转  
								console.log('需要180度旋转');
								rotateImg(this, 'right', canvas); //转两次  
								rotateImg(this, 'right', canvas);
								break;
						}
					}
					base64 = canvas.toDataURL("image/jpeg", quality);
				}

				//计算base64文件流大小
				var strLength = base64.length;
				var fileLength = parseInt(strLength - (strLength / 8) * 2);
				// 由字节转换为KB
				var size = "";
				size = (fileLength / 1024).toFixed(2);
				console.log("base64=" + size);

				//调用
				html.updateShopLogo(base64);
			};
		};
		oReader.readAsDataURL(file);
	}
}
/**
 * 对图片旋转处理
 * @param {Object} img
 * @param {Object} direction
 * @param {Object} canvas
 */
function rotateImg(img, direction, canvas) {
	//最小与最大旋转方向,图片旋转4次后回到原方向    
	var min_step = 0;
	var max_step = 3;
	//var img = document.getElementById(pid);    
	if (img == null) return;
	//img的高度和宽度不能在img元素隐藏后获取,否则会出错    
	var height = img.height;
	var width = img.width;
	//var step = img.getAttribute('step');    
	var step = 2;
	if (step == null) {
		step = min_step;
	}
	if (direction == 'right') {
		step++;
		//旋转到原位置,即超过最大值    
		step > max_step && (step = min_step);
	} else {
		step--;
		step < min_step && (step = max_step);
	}
	//旋转角度以弧度值为参数    
	var degree = step * 90 * Math.PI / 180;
	var ctx = canvas.getContext('2d');
	switch (step) {
		case 0:
			canvas.width = width;
			canvas.height = height;
			ctx.drawImage(img, 0, 0);
			break;
		case 1:
			canvas.width = height;
			canvas.height = width;
			ctx.rotate(degree);
			ctx.drawImage(img, 0, -height);
			break;
		case 2:
			canvas.width = width;
			canvas.height = height;
			ctx.rotate(degree);
			ctx.drawImage(img, -width, -height);
			break;
		case 3:
			canvas.width = height;
			canvas.height = width;
			ctx.rotate(degree);
			ctx.drawImage(img, -width, 0);
			break;
	}
}
/**
 * 图片大小
 */
function formatSize(size, len, units) {
	let unit;
	units = units || ['B', 'K', 'M', 'G', 'TB'];
	while ((unit = units.shift()) && size > 1024) {
		size = size / 1024;
	}
	return (unit === 'B' ? size : size.toFixed(len === undefined ? 2 : len)) + unit;
}

 

Guess you like

Origin blog.csdn.net/luolinyin/article/details/108097557