uniapp h5上传图片对图片进行压缩旋转处理

偏执的太偏执、 2023-06-15 04:57 66阅读 0赞

之前写过一个关于vue的上传图的旋转处理。可以直接点击查看:使用vue进行移动端上传图

场景:uniapp开发的h5项目,需要内嵌在app中运行,在项目首页有一块是自定义上传日历背景图,并且需要进行裁剪。
最开始直接使用的插件市场的插件,但是由于webview的原因,该项目内嵌app后在ios上出现了无法解决的bug。故弃用了插件,并且由于需求调整目前只进行图片的上传旋转处理。(下面着重旋转的处理)

思路:

1、参考vue的处理方法,需要exif.js 获取到图片meta信息中的旋转角度,故首先需要引入exif.js,(本人直接从bootcdn上搜索下载的exif.min.js )(使用import引入本地文件的方式尝试了下没有成功,放弃了。由于项目本身需要存在了引入第三方的js方法所以exifjs是通过动态添加js的方式全局引入的)

2、通过uni.chooseImage 获取到图片的临时路径,并且将blob临时路径转化为 file文件用于exif获取图片的旋转值

3、根据获取到旋转值(有:1 3 6 8),如下:

  1. //如果方向角不为1,都需要进行旋转
  2. switch (Orientation) {
  3. case 6: //需要顺时针(向右)90度旋转
  4. console.log('(向右)90度旋转');
  5. break;
  6. case 8: //需要逆时针(向左)90度旋转
  7. console.log('向左)90度旋转');
  8. break;
  9. case 3: //需要180度旋转 转两次
  10. console.log('需要180度旋转');
  11. break;
  12. default:
  13. break;
  14. }

4、根据网上搜索的处理图片旋转方法或者从往期vue的上传图博客中提到的,对图片进行旋转处理,最终拿到base64的图片信息然后对图片进行上传。(1.直接上传base64 ;2.将base64转化为blob文件后再传后台)

具体代码如下:

  1. 1
  2. choiceImg(){
  3. var that = this;
  4. let maxWidth = 500; //压缩图片最大宽度
  5. let Orientation = 1;
  6. uni.chooseImage({
  7. count: 1, // 能够选择的图片数量
  8. sizeType: ['original', 'compressed'], // original: 原图, compressed: 压缩图, 默认二者都有
  9. sourceType: ['album'], // album: 从相册选择 camera: 相机拍照
  10. success: res => {
  11. let imgArr = res.tempFilePaths; // 所选择图片的临时路径数组
  12. //BlobUrl转blob数据
  13. uni.showToast({
  14. icon: "none",
  15. title: "图片处理中..."
  16. })
  17. //blob数据转file
  18. this.objectURLToBlob(imgArr[0], function(blob) {
  19. let files = new window.File([blob], 'file.name', { type: 'file.type' });
  20. console.log('获取图片文件', files);
  21. EXIF.getData(files, async function() {
  22. let or = EXIF.getTag(this, 'Orientation'); //这个Orientation 就是我们判断需不需要旋转的值了,有1、3、6、8
  23. console.log(or);
  24. Orientation = or;
  25. var img = null;
  26. var canvas = null;
  27. await that.comprossImage(imgArr[0], maxWidth, function(e) {
  28. img = e.img;
  29. canvas = e.canvas;
  30. });
  31. let baseStr = '';
  32. //如果方向角不为1,都需要进行旋转
  33. switch (Orientation) {
  34. case 6: //需要顺时针(向右)90度旋转
  35. console.log('(向右)90度旋转');
  36. baseStr = that.rotateImg(img, 'right', canvas);
  37. break;
  38. case 8: //需要逆时针(向左)90度旋转
  39. console.log('向左)90度旋转');
  40. baseStr = rotateImg(img, 'left', canvas);
  41. break;
  42. case 3: //需要180度旋转 转两次
  43. console.log('需要180度旋转');
  44. baseStr = that.rotateImg(img, 'right', canvas, 2);
  45. break;
  46. default:
  47. baseStr = that.rotateImg(img, '', canvas);
  48. break;
  49. }
  50. });
  51. });
  52. }
  53. });
  54. }
  55. 21中使用到的将blob转化为file方法 和图片的压缩方法
  56. objectURLToBlob(url, callback) {
  57. var http = new XMLHttpRequest();
  58. http.open('GET', url, true);
  59. http.responseType = 'blob';
  60. http.onload = function(e) {
  61. if (this.status == 200 || this.status === 0) {
  62. callback(this.response);
  63. }
  64. };
  65. http.send();
  66. },
  67. async comprossImage(imgSrc, maxWidth, func) {
  68. if (!imgSrc) return 0;
  69. return new Promise((resolve, reject) => {
  70. uni.getImageInfo({
  71. src: imgSrc,
  72. success(res) {
  73. let img = new Image();
  74. img.src = res.path;
  75. console.log(img);
  76. let canvas = document.createElement('canvas');
  77. let obj = new Object();
  78. obj.img = img;
  79. obj.canvas = canvas;
  80. resolve(func(obj));
  81. }
  82. });
  83. });
  84. },
  85. 3、图片的旋转处理
  86. rotateImg(img, direction, canvas, times = 1) {
  87. console.log('开始旋转');
  88. //最小与最大旋转方向,图片旋转4次后回到原方向
  89. var min_step = 0;
  90. var max_step = 3;
  91. if (img == null) return;
  92. //img的高度和宽度不能在img元素隐藏后获取,否则会出错
  93. var height = img.height;
  94. var width = img.width;
  95. let maxWidth = 500;
  96. let canvasWidth = width; //图片原始长宽
  97. let canvasHeight = height;
  98. let base = canvasWidth / canvasHeight;
  99. console.log(maxWidth);
  100. if (canvasWidth > maxWidth) {
  101. canvasWidth = maxWidth;
  102. canvasHeight = Math.floor(canvasWidth / base);
  103. }
  104. width = canvasWidth;
  105. height = canvasHeight;
  106. var step = 0;
  107. if (step == null) {
  108. step = min_step;
  109. }
  110. if (direction == 'right') {
  111. step += times;
  112. //旋转到原位置,即超过最大值
  113. step > max_step && (step = min_step);
  114. } else if (direction == 'left') {
  115. step -= times;
  116. step < min_step && (step = max_step);
  117. } else {
  118. //不旋转
  119. step = 0;
  120. }
  121. //旋转角度以弧度值为参数
  122. var degree = (step * 90 * Math.PI) / 180;
  123. var ctx = canvas.getContext('2d');
  124. // console.log(degree)
  125. // console.log(step)
  126. switch (step) {
  127. case 1:
  128. console.log('右旋转 90度');
  129. canvas.width = height;
  130. canvas.height = width;
  131. ctx.rotate(degree);
  132. ctx.drawImage(img, 0, -height, width, height);
  133. break;
  134. case 2:
  135. //console.log('旋转 180度')
  136. canvas.width = width;
  137. canvas.height = height;
  138. ctx.rotate(degree);
  139. ctx.drawImage(img, -width, -height, width, height);
  140. break;
  141. case 3:
  142. console.log('左旋转 90度');
  143. canvas.width = height;
  144. canvas.height = width;
  145. ctx.rotate(degree);
  146. ctx.drawImage(img, -width, 0, width, height);
  147. break;
  148. default:
  149. //不旋转
  150. canvas.width = width;
  151. canvas.height = height;
  152. ctx.drawImage(img, 0, 0, width, height);
  153. break;
  154. }
  155. let baseStr = canvas.toDataURL('image/jpeg', 1);
  156. // console.log(baseStr)
  157. // return baseStr;
  158. // replace("data:image/jpeg;base64,", "")
  159. // 将base64转化为blob文件进行图片上传,(考虑到转化后再上传耗费时间暂时没有使用,如果需要base64ToPath 方法可百度或者私信我)
  160. // base64ToPath(baseStr).then(tempPath => {
  161. // this.uploadBgImg(tempPath)
  162. // });
  163. // 自定义上传请求
  164. this.uploadBaseImg(baseStr);
  165. },



追加:

  1. export function pathToBase64(path) {
  2. return new Promise(function(resolve, reject) {
  3. if (typeof window === 'object' && 'document' in window) {
  4. var canvas = document.createElement('canvas')
  5. var c2x = canvas.getContext('2d')
  6. var img = new Image
  7. img.setAttribute('crossOrigin', 'anonymous');
  8. // img.crossOrigin = "anonymous"
  9. img.onload = function() {
  10. canvas.width = img.width
  11. canvas.height = img.height
  12. c2x.drawImage(img, 0, 0)
  13. resolve(canvas.toDataURL())
  14. }
  15. img.onerror = reject
  16. img.src = path
  17. return
  18. }
  19. if (typeof plus === 'object') {
  20. var bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
  21. bitmap.load(path, function() {
  22. try {
  23. var base64 = bitmap.toBase64Data()
  24. } catch (error) {
  25. reject(error)
  26. }
  27. bitmap.clear()
  28. resolve(base64)
  29. }, function(error) {
  30. bitmap.clear()
  31. reject(error)
  32. })
  33. return
  34. }
  35. if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
  36. wx.getFileSystemManager().readFile({
  37. filePath: path,
  38. encoding: 'base64',
  39. success: function(res) {
  40. resolve('data:image/png;base64,' + res.data)
  41. },
  42. fail: function(error) {
  43. reject(error)
  44. }
  45. })
  46. return
  47. }
  48. reject(new Error('not support'))
  49. })
  50. }
  51. export function base64ToPath(base64) {
  52. return new Promise(function(resolve, reject) {
  53. if (typeof window === 'object' && 'document' in window) {
  54. base64 = base64.split(',')
  55. var type = base64[0].match(/:(.*?);/)[1]
  56. var str = atob(base64[1])
  57. var n = str.length
  58. var array = new Uint8Array(n)
  59. while (n--) {
  60. array[n] = str.charCodeAt(n)
  61. }
  62. return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], { type: type })))
  63. }
  64. var extName = base64.match(/data\:\S+\/(\S+);/)
  65. if (extName) {
  66. extName = extName[1]
  67. } else {
  68. reject(new Error('base64 error'))
  69. }
  70. var fileName = Date.now() + '.' + extName
  71. if (typeof plus === 'object') {
  72. var bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
  73. bitmap.loadBase64Data(base64, function() {
  74. var filePath = '_doc/uniapp_temp/' + fileName
  75. bitmap.save(filePath, {}, function() {
  76. bitmap.clear()
  77. resolve(filePath)
  78. }, function(error) {
  79. bitmap.clear()
  80. reject(error)
  81. })
  82. }, function(error) {
  83. bitmap.clear()
  84. reject(error)
  85. })
  86. return
  87. }
  88. if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
  89. var filePath = wx.env.USER_DATA_PATH + '/' + fileName
  90. wx.getFileSystemManager().writeFile({
  91. filePath: filePath,
  92. data: base64.replace(/^data:\S+\/\S+;base64,/, ''),
  93. encoding: 'base64',
  94. success: function() {
  95. resolve(filePath)
  96. },
  97. fail: function(error) {
  98. reject(error)
  99. }
  100. })
  101. return
  102. }
  103. reject(new Error('not support'))
  104. })
  105. }

发表评论

表情:
评论列表 (有 0 条评论,66人围观)

还没有评论,来说两句吧...

相关阅读

    相关 iOS-图片压缩处理

    iOS图片压缩,想必这是一个比较大切值得深入的一个研究。所以太深入的这里我也不会去讲,之所以写这篇,是因为我们在开发中,因为iphone拍照后,直接上传的图片大多数像素比较高,

    相关 h5图片

    做了一个h5多图片上传 只要了解了 基本原理,那就很好理解了,可以看看注释或者在网上找找原理 <!doctype html> <html>