当前位置:   article > 正文

uniapp --- 实现图片压缩(兼容H5)

uniapp --- 实现图片压缩(兼容H5)

目录

创建组件

在 template 中添加组件

方法说明:

compress() 方法参数:

progress 方法回调对象属性详细说明:

源码示例: 

 thank


Canvas 是 HTML5 提供的一个用于在网页上绘制图形的元素,它可以实现图片压缩的功能。而结和UnoApp是一种基于Canvas的图形编辑工具库,它提供了丰富的API和功能,可以帮助开发者在网页上实现各种图形编辑和处理操作。

实现图片压缩的原理在结和UnoApp中也是类似的,主要是通过Canvas的绘图功能来重新绘制图片并调整尺寸和质量。下面将详细介绍结和UnoApp实现图片压缩的步骤:

创建组件
  1. <template>
  2. <view class="compress" v-if="canvasId">
  3. <canvas :canvas-id="canvasId" :style="{ width: canvasSize.width, height: canvasSize.height }"></canvas>
  4. </view>
  5. </template>
  6. <script>
  7. export default {
  8. data() {
  9. return {
  10. pic: '',
  11. canvasSize: {
  12. width: 0,
  13. height: 0
  14. },
  15. canvasId: ''
  16. };
  17. },
  18. mounted() {
  19. // 创建 canvasId
  20. if (!uni || !uni._helang_compress_canvas) {
  21. uni._helang_compress_canvas = 1;
  22. } else {
  23. uni._helang_compress_canvas++;
  24. }
  25. this.canvasId = `compress-canvas${uni._helang_compress_canvas}`;
  26. },
  27. methods: {
  28. // 压缩
  29. compressFun(params) {
  30. return new Promise(async (resolve, reject) => {
  31. // 等待图片信息
  32. let info = await this.getImageInfo(params.src)
  33. .then((info) => info)
  34. .catch(() => null);
  35. if (!info) {
  36. reject('获取图片信息异常');
  37. return;
  38. }
  39. // 设置最大 & 最小 尺寸
  40. const maxSize = params.maxSize || 1080;
  41. const minSize = params.minSize || 640;
  42. // 当前图片尺寸
  43. let { width, height } = info;
  44. // 非 H5 平台进行最小尺寸校验
  45. // #ifndef H5
  46. if (width <= minSize && height <= minSize) {
  47. resolve(params.src);
  48. return;
  49. }
  50. // #endif
  51. // 最大尺寸计算
  52. //(图像的宽度和高度是否超过最大尺寸。如果其中任一维度超过最大尺寸,代码将对图像进行调整,以使其适应最大尺寸并保持其宽高比。)
  53. // 这样可以确保图像在调整大小后仍保持原始比例,并且不会超过指定的最大尺寸
  54. if (width > maxSize || height > maxSize) {
  55. if (width > height) {
  56. height = Math.floor(height / (width / maxSize));
  57. width = maxSize;
  58. } else {
  59. width = Math.floor(width / (height / maxSize));
  60. height = maxSize;
  61. }
  62. }
  63. // 设置画布尺寸
  64. this.$set(this, 'canvasSize', {
  65. width: `${width}px`,
  66. height: `${height}px`
  67. });
  68. // Vue.nextTick 回调在 App 有异常,则使用 setTimeout 等待DOM更新
  69. setTimeout(() => {
  70. // 创建 canvas 绘图上下文(指定 canvasId)。在自定义组件下,第二个参数传入组件实例this,以操作组件内 <canvas/> 组件
  71. // Tip: 需要指定 canvasId,该绘图上下文只作用于对应的 <canvas/>
  72. const ctx = uni.createCanvasContext(this.canvasId, this);
  73. // 清除画布上在该矩形区域内的内容。(x,y,宽,高)
  74. ctx.clearRect(0, 0, width, height);
  75. // 绘制图像到画布。(所要绘制的图片资源,x,y,宽,高)
  76. ctx.drawImage(info.path, 0, 0, width, height);
  77. // 将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中。
  78. // 本次绘制是否接着上一次绘制,即reserve参数为false,则在本次调用drawCanvas绘制之前native层应先清空画布再继续绘制;若reserver参数为true,则保留当前画布上的内容,本次调用drawCanvas绘制的内容覆盖在上面,默认 false
  79. // 绘制完成后回调
  80. ctx.draw(false, () => {
  81. // 把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径。在自定义组件下,第二个参数传入自定义组件实例,以操作组件内 <canvas> 组件。
  82. uni.canvasToTempFilePath(
  83. {
  84. x: 0, //画布x轴起点(默认0
  85. y: 0, //画布y轴起点(默认0
  86. width: width, //画布宽度(默认为canvas宽度-x)
  87. height: height, //画布高度(默认为canvas高度-y
  88. destWidth: width, //图片宽度(默认为 width * 屏幕像素密度)
  89. destHeight: height, //输出图片高度(默认为 height * 屏幕像素密度)
  90. canvasId: this.canvasId, //画布标识,传入 <canvas/> 的 canvas-id(支付宝小程序是id、其他平台是canvas-id)
  91. fileType: params.fileType || 'png', //目标文件的类型,只支持 'jpg''png'。默认为 'png'
  92. quality: params.quality || 0.9, //图片的质量,取值范围为 (0, 1],不在范围内时当作1.0处理
  93. success: (res) => {
  94. // 在H5平台下,tempFilePath 为 base64
  95. resolve(res.tempFilePath);
  96. },
  97. fail: (err) => {
  98. reject(null);
  99. }
  100. },
  101. this
  102. );
  103. });
  104. }, 300);
  105. });
  106. },
  107. // 获取图片信息
  108. getImageInfo(src) {
  109. return new Promise((resolve, reject) => {
  110. uni.getImageInfo({
  111. src,
  112. success: (info) => {
  113. resolve(info);
  114. },
  115. fail: (err) => {
  116. console.log(err, 'err===获取图片信息');
  117. reject(null);
  118. }
  119. });
  120. });
  121. },
  122. // 批量压缩
  123. async compress(params) {
  124. // 初始化状态变量
  125. let [index, done, fail] = [0, 0, 0];
  126. let paths = [];
  127. // 处理待压缩图片列表
  128. let waitList = Array.isArray(params.src) ? params.src : [params.src];
  129. // 批量压缩方法
  130. let batch = async () => {
  131. while (index < waitList.length) {
  132. try {
  133. const path = await next();
  134. done++;
  135. paths.push(path);
  136. params.progress?.({ done, fail, count: waitList.length });
  137. } catch (error) {
  138. fail++;
  139. params.progress?.({ done, fail, count: waitList.length });
  140. }
  141. index++;
  142. }
  143. };
  144. // 单个图片压缩方法
  145. let next = () => {
  146. const currentSrc = waitList[index];
  147. return this.compressFun({
  148. src: currentSrc,
  149. maxSize: params.maxSize,
  150. fileType: params.fileType,
  151. quality: params.quality,
  152. minSize: params.minSize
  153. });
  154. };
  155. // 返回Promise并处理结果
  156. return new Promise((resolve, reject) => {
  157. try {
  158. batch()
  159. .then(() => {
  160. if (typeof params.src === 'string') {
  161. resolve(paths[0]);
  162. } else {
  163. resolve(paths);
  164. }
  165. })
  166. .catch((error) => {
  167. reject(error);
  168. });
  169. } catch (error) {
  170. reject(error);
  171. }
  172. });
  173. }
  174. }
  175. };
  176. </script>
  177. <style lang="scss" scoped>
  178. .compress {
  179. position: fixed;
  180. width: 12px;
  181. height: 12px;
  182. overflow: hidden;
  183. top: -99999px;
  184. left: 0;
  185. }
  186. </style>

在 script 中引用组件

  1. import helangCompress from '../../components/helang-compress/helang-compress';
  2. export default {
  3. components: {
  4. helangCompress
  5. }
  6. }
在 template 中添加组件
<helang-compress ref="helangCompress"></helang-compress>
方法说明:
方法名可传参数必填说明
compress()Object【单张压缩】设置压缩的图片及压缩尺寸和压缩质量,参数详情请阅读下方 compress()方法参数
compress() 方法参数
参数名类型必填默认值说明
srcString / Array-待压缩的图片地址,由相册选择或拍照获取。注意:若src的值为String压缩成功后则返回String,若为Array,压缩成功后则返回Array
maxSizeNumber1080压缩后的最大尺寸
fileTypeString'png'压缩后的文件类型,可选值 jpg、png
qualityNumber0.9压缩后的质量(仅jpg类型有效,原因可自行阅读官方canvas文档),可选值 0 ~ 1,值越大越清晰(图片也越大)
minSizeNumber640最小压缩尺寸,图片尺寸小于该时值不压缩,非H5平台有效。若想忽略该设置可以将该值设置为一个极小的值,比如一个负数(不能是0)

为使插件在 H5 平台统一返回 base64 数据,则故意取消 H5 平台对 minSize 的设置。H5平台压缩后的图片路径是 base64 格式,有跨平台需求须注意

progress 方法回调对象属性详细说明:
参数名类型说明
doneNumber已完成压缩的数量
failNumber压缩失败的数量
countNumber总共需要压缩的数量
源码示例: 
  1. // 单张压缩
  2. this.$refs.helangCompress.compressFun({
  3. src:this.paths[0],
  4. maxSize:800,
  5. fileType:'jpg',
  6. quality:0.85,
  7. minSize:640 //最小压缩尺寸,图片尺寸小于该时值不压缩,非H5平台有效。若需要忽略该设置,可设置为一个极小的值,比如负数。
  8. }).then((res)=>{
  9. // 压缩成功回调
  10. }).catch((err)=>{
  11. // 压缩失败回调
  12. })
  13. // 批量压缩
  14. this.$refs.helangCompress.compress({
  15. src:this.paths,
  16. maxSize:800,
  17. fileType:'jpg',
  18. quality:0.85,
  19. progress:(res)=>{
  20. console.log('压缩进度');
  21. console.log(res);
  22. }
  23. }).then((res)=>{
  24. // 压缩成功回调
  25. }).catch((err)=>{
  26. // 压缩成功回调
  27. })
 thank

图片压缩 - 可以自定义压缩尺寸和压缩质量 - DCloud 插件市场

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/460648
推荐阅读
相关标签
  

闽ICP备14008679号