Angular image cropping cropperjs application and the problem of rotating the image 90 degrees in iOS and compressing the image

Angular image cropping cropperjs application base64 to image use exif-js rotation image compression image

Why do you need to compress pictures?

When you crop the picture with cropper, you need to use canvas to redraw your picture for cropping. Because the picture is large, the drawing is very slow, and the user operability is not good, and the ios will also appear stuck.

Why use exif-js to rotate

When uploading photos on mobile phones with html5+canvas, I found that the vertical photos uploaded by ios phones would rotate 90 degrees counterclockwise, and the horizontal photos did not have this problem. After
hesitating, the pictures taken by Apple phones would be larger. When the pictures were larger than 2M, the pictures would be Automatically rotate 90 degrees, when you cut the picture, a rotated picture will be generated. In order to circumvent this problem, we need to re-canvas the photos.
This problem also exists on Android phones with 3 stars

Upload code

The official website says very clearly that npm install or bower install introduces files. Then there is the application. I first started using import to introduce it, but I didn't find any problem (I don't know if it was my problem or the problem of the framework), and always said that the support file of cropper could not be found. Very annoying. So it was very rude to choose to directly introduce js and css in index.html

// 引入cropperjs
   <link href="lazyload/lib/cropperjs/dist/cropper.min.css" rel="stylesheet">
   <script src="lazyload/lib/cropperjs/dist/cropper.min.js"></script>

Because you directly import cropperjs directly in index.html, you don't need to import it directly in the controller.
Note: The img tag must be in a div or other block-level element, otherwise the cropping effect will not be generated.

// 当然之前你必须执行上传图片操作resp.data['DATA'][0]这个为我上传图片的id vm.photo为图片的访问地址(不是本地图片)
var cropper
var image = document.getElementById('phtotoperson');
 cropper = new Cropper(image, {
    
    
	viewMode:1,
	guides:false, // 是否显示在裁剪框上方的虚线
	aspectRatio:295/413,//一寸照片裁剪尺寸
	cropBoxResizable:false //裁剪框的大小不能改变默认可以改变
	resizable:false,
	dragMode:"move",
	dragCrop:false,//不允许重新开裁剪框
	});
   vm.photo ='/file-server/files/download/'+ resp.data['DATA'][0];
   
	cropper.replace(vm.photo); 
//上个代码是根据你图片路径改变重新绘制,比如你点击上传图片之后发现上传错误想返回从新上传可能就会出现还是你第一次上传的图片。		
//因为图片裁剪下来的为base64的图片,下边的方法会将base64格式的图片转换成可上传用的图片
function dataURLtoBlob(dataurl) {
    
     
		var arr = dataurl.split(','),
			mime = arr[0].match(/:(.*?);/)[1],
			bstr = atob(arr[1]),
			n = bstr.length,
			u8arr = new Uint8Array(n);
		while (n--) {
    
    
			u8arr[n] = bstr.charCodeAt(n);
		}
		return new Blob([u8arr], {
    
     type: mime });
	};
	//将上传的图片命名成你希望的名称fileName表示想要的名称
	function blobToFile(theBlob, fileName){
    
    
		theBlob.lastModifiedDate = new Date();
		theBlob.name = fileName;
		return theBlob;
	};

Use exif.js plug-in to solve the problem of rotating 90 degrees of vertical photos uploaded by ios mobile phones

需要在你的项目中安装exif-js
npm install exif-js --save
//判断是否需要旋转
function selectFileImage(file) {
    
    
			console.log(file);
			//图片方向角
			var Orientation = null;
			
			if (file) {
    
    
				console.log("正在上传,请稍后...");
				if (!file) return;
					if (['image/jpg', 'image/jpeg', 'image/png'].indexOf(file.type) < 0) {
    
    
					gToast.open('请上传图片,请重新选择', {
    
     timeout: 3000 });
					return;
					}
					if (file.size > 10 * 1024 * 1024) {
    
    
					gToast.open('请上传不超过10M的图片,请重新选择', {
    
     timeout: 3000 });
					return;
					}
				// var URL = URL || webkitURL;
				//获取照片方向角属性,用户旋转控制
				EXIF.getData(file, function() {
    
    
				// alert(EXIF.pretty(this));
					EXIF.getAllTags(this); 
					//alert(EXIF.getTag(this, 'Orientation')); 
					Orientation = EXIF.getTag(this, 'Orientation');
					// alert(Orientation);
					//return;
				});
				
				var oReader = new FileReader();
				oReader.onload = function(e) {
    
    
					//var blob = URL.createObjectURL(file);
					//_compress(blob, file, basePath);
					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 base64 = null;
						//修复ios
						if (navigator.userAgent.match(/iphone/i)) {
    
    
							console.log('iphone');
							//alert(expectWidth + ',' + expectHeight);
							//如果方向角不为1,都需要进行旋转 added by lzk
							if(Orientation != "" && Orientation != 1){
    
    
								alert('旋转处理',Orientation);
								switch(Orientation){
    
    
								 	case 6://需要顺时针(向左)90度旋转
								 		// alert('需要顺时针(向左)90度旋转');
								 		rotateImg(this,'left',canvas);
								 		break;
								 	case 8://需要逆时针(向右)90度旋转
								 		// alert('需要顺时针(向右)90度旋转');
								 		rotateImg(this,'right',canvas);
								 		break;
								 	case 3://需要180度旋转
								 		// alert('需要180度旋转');
										rotateImg(this,'right',canvas);//转两次
										rotateImg(this,'right',canvas);
										break;
								}		
							}
							
							/*var mpImg = new MegaPixImage(image);
							mpImg.render(canvas, {
								maxWidth: 800,
								maxHeight: 1200,
								quality: 0.8,
								orientation: 8
							});*/
							base64 = canvas.toDataURL("image/jpeg", 0.8);
							//使用压缩
							dealImage(base64, 800, uploadImg);
							// console.log(blobToFile(dataURLtoBlob(base), file.name))
						}else if (navigator.userAgent.match(/Android/i)) {
    
    // 修复android
						AndroiduploadImg(file);
						}else{
    
    
							//alert(Orientation);
							if(Orientation != "" && Orientation != 1){
    
    
								//alert('旋转处理');
								switch(Orientation){
    
    
								 	case 6://需要顺时针(向左)90度旋转
								 		// alert('需要顺时针(向左)90度旋转');
								 		rotateImg(this,'left',canvas);
								 		break;
								 	case 8://需要逆时针(向右)90度旋转
								 		// alert('需要顺时针(向右)90度旋转');
								 		rotateImg(this,'right',canvas);
								 		break;
								 	case 3://需要180度旋转
								 		// alert('需要180度旋转');
										rotateImg(this,'right',canvas);//转两次
										rotateImg(this,'right',canvas);
										break;
								}		
							}	
							base64 = canvas.toDataURL("image/jpeg", 0.8);
							dealImage(base64, 800, uploadImg);			
						}
						
					};
				};
				oReader.readAsDataURL(file);
			}
		}
 
		//对图片旋转处理 
		function rotateImg(img, direction,canvas) {
    
      
				//alert(img);
				//最小与最大旋转方向,图片旋转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);  
				}  
				//img.setAttribute('step', step);  
				/*var canvas = document.getElementById('pic_' + pid);  
				if (canvas == null) {  
					img.style.display = 'none';  
					canvas = document.createElement('canvas');  
					canvas.setAttribute('id', 'pic_' + pid);  
					img.parentNode.appendChild(canvas);  
				}  */
				//旋转角度以弧度值为参数  
				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;  
				}  
			}  
		// 上传照片
		vm.uploadAvatar = function () {
    
    
			var file = vm.phtoto;
			selectFileImage(file);
			
		  };
		//从新绘制的图片可能较大ios处理裁剪的时候加载很慢。所以我们先将图片进行压缩在进行裁剪
		//压缩方法
		function dealImage(base64, w, callback) {
    
    
			var newImage = new Image();
			var quality = 0.6;    //压缩系数0-1之间
			newImage.src = base64;
			newImage.setAttribute("crossOrigin", 'Anonymous');	//url为外域时需要
			var imgWidth, imgHeight;
			newImage.onload = function () {
    
    
				imgWidth = this.width;
				imgHeight = this.height;
				var canvas = document.createElement("canvas");
				var ctx = canvas.getContext("2d");
				if (Math.max(imgWidth, imgHeight) > w) {
    
    
					if (imgWidth > imgHeight) {
    
    
						canvas.width = w;
						canvas.height = w * imgHeight / imgWidth;
					} else {
    
    
						canvas.height = w;
						canvas.width = w * imgWidth / imgHeight;
					}
				} else {
    
    
					canvas.width = imgWidth;
					canvas.height = imgHeight;
					quality = 0.6;
				}
				ctx.clearRect(0, 0, canvas.width, canvas.height);
				ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
				var base64 = canvas.toDataURL("image/jpeg", quality); //压缩语句
				// 如想确保图片压缩到自己想要的尺寸,如要求在50-150kb之间,请加以下语句,quality初始值根据情况自定
				// while (base64.length / 1024 > 150) {
    
    
				// 	quality -= 0.01;
				// 	base64 = canvas.toDataURL("image/jpeg", quality);
				// }
				// 防止最后一次压缩低于最低尺寸,只要quality递减合理,无需考虑
				// while (base64.length / 1024 < 50) {
    
    
				// 	quality += 0.001;
				// 	base64 = canvas.toDataURL("image/jpeg", quality);
				// }
				callback(base64);//必须通过回调函数返回,否则无法及时拿到该值
			}
		}

Guess you like

Origin blog.csdn.net/lbchenxy/article/details/97272784