当前位置:   article > 正文

uniapp 微信小程序使用we-cropper实现图片裁剪_小程序图片裁剪源码下载

小程序图片裁剪源码下载

一、背景

需求:需要实现用户上传图像并进行裁剪操作的功能。为了实现这一需求,使用了uniapp作为开发框架,并结合了we-cropper这一图像裁剪插件来实现图片裁剪的功能。

源码地址:https://github.com/we-plugin/we-cropper/

二、具体操作

2.1、在index.vue 页面点击头像上传获取临时路径 ,并跳转至cropper组件

  1. <template>
  2. <view>
  3. <view class="upload box" @click="chooseImage">
  4. <label>上传图片</label>
  5. <view class="right">
  6. <view class="upload-box">
  7. <image :src="touxiang" mode="widthFix" :style="{width:imgSize,height:imgSize,'backgroundSize': 'cover','marginTop': imgMargin +'rpx'}" />
  8. <text class="tips" v-show="isShow">点击上传</text>
  9. </view>
  10. </view>
  11. </view>
  12. <view style="position: fixed; top: 9999px;">
  13. <canvas canvas-id="picCanvas" id='picCanvas' class="pic-canvas" :style="{width: imgWidth + 'px', height: imgHeight + 'px'}"></canvas>
  14. </view>
  15. </view>
  16. </template>
  17. <script>
  18. export default {
  19. data() {
  20. return {
  21. touxiang: '/static/upload.png',
  22. isShow: true,
  23. imgSize: '128rpx',
  24. imgMargin: 30,
  25. imgWidth: 0,
  26. imgHeight: 0,
  27. isActionBtn: false,
  28. }
  29. },
  30. methods: {
  31. chooseImage(){
  32. uni.navigateTo({
  33. url: "/pages/cropper/cropper?destWidth=200&rectWidth=200&fileType=jpg"
  34. })
  35. //接收cropper页面传递的图片路径
  36. uni.$on('Cropper', path => {
  37. if(path){
  38. // 上传图片方法
  39. this.update(path);
  40. this.imgSize = '98%'
  41. this.imgMargin = 0
  42. this.touxiang = path
  43. this.isShow = false
  44. }
  45. });
  46. },
  47. update(filePath) {
  48. this.touxiang = filePath
  49. this.isActionBtn = true
  50. //根据其他业务需求,调取接口,保存头像
  51. // ......
  52. },
  53. }
  54. }
  55. </script>
  56. <style lang="scss" scoped>
  57. .upload {
  58. display: flex;
  59. box-sizing: border-box;
  60. padding: 20rpx 30rpx;
  61. width: 710rpx;
  62. height: 300rpx;
  63. justify-content: center;
  64. margin-top: 20rpx;
  65. position: relative;
  66. label {
  67. width: 158rpx;
  68. color: #333333;
  69. font-size: 30spx;
  70. }
  71. .right {
  72. display: flex;
  73. width: 492rpx;
  74. height: 250rpx;
  75. .upload-box {
  76. display: flex;
  77. flex-direction: column;
  78. align-items: center;
  79. justify-content: center;
  80. width: 205rpx;
  81. height: 100%;
  82. background-color: #F0F0F0;
  83. border-radius: 10rpx;
  84. image {
  85. margin-left: auto;
  86. margin-right: auto;
  87. }
  88. text {
  89. margin-top: 10rpx;
  90. width: 100%;
  91. font-size: 20spx;
  92. color: #999999;
  93. text-align: center;
  94. }
  95. }
  96. }
  97. }
  98. .pic-canvas {
  99. width: 205px;
  100. height: 250px;
  101. }
  102. </style>

2.2、cropper组件进行图片裁剪操作

  1. <template>
  2. <view class="content">
  3. <view class="cropper-wrapper" :style="{ height: cropperOpt.height + 'px' }">
  4. <canvas
  5. class="cropper"
  6. :disable-scroll="true"
  7. @touchstart="touchStart"
  8. @touchmove="touchMove"
  9. @touchend="touchEnd"
  10. :style="{ width: cropperOpt.width, height: cropperOpt.height, backgroundColor: 'rgba(0, 0, 0, 0.8)' }"
  11. canvas-id="cropper"
  12. id="cropper"
  13. ></canvas>
  14. <canvas
  15. class="cropper"
  16. :disable-scroll="true"
  17. :style="{
  18. position: 'fixed',
  19. top: `-${cropperOpt.width * cropperOpt.pixelRatio}px`,
  20. left: `-${cropperOpt.height * cropperOpt.pixelRatio}px`,
  21. width: `${cropperOpt.width * cropperOpt.pixelRatio}px`,
  22. height: `${cropperOpt.height * cropperOpt.pixelRatio}`
  23. }"
  24. canvas-id="targetId"
  25. id="targetId"
  26. ></canvas>
  27. </view>
  28. <view class="cropper-buttons safe-area-padding" :style="{ height: bottomNavHeight + 'px',color:cropperOpt.boundStyle.color}">
  29. <view class="upload" @tap="uploadTap">选择图片</view>
  30. <view class="upload btn" @tap="uploadTap">重新选取</view>
  31. <view class="getCropperImage btn" :style="{ backgroundColor: cropperOpt.boundStyle.color }" @tap="getCropperImage(false)">完成</view>
  32. </view>
  33. </view>
  34. </template>
  35. <script>
  36. import WeCropper from 'we-cropper';
  37. export default {
  38. props: {
  39. boundStyle: {
  40. type: Object,
  41. default() {
  42. return {
  43. lineWidth: 4,
  44. borderColor: 'rgb(245, 245, 245)',
  45. mask: 'rgba(0, 0, 0, 0.35)'
  46. };
  47. }
  48. }
  49. },
  50. data() {
  51. return {
  52. // 底部导航的高度
  53. bottomNavHeight: 50,
  54. originWidth: 200,
  55. width: 0,
  56. height: 0,
  57. cropper: '',
  58. cropperOpt: {
  59. id: 'cropper',
  60. targetId: 'targetCropper',
  61. pixelRatio: 1,
  62. width: 0,
  63. height: 0,
  64. scale: 2.5,
  65. zoom: 8,
  66. cut: {
  67. x: (this.width - this.originWidth) / 2,
  68. y: (this.height - this.originWidth) / 2,
  69. width: this.originWidth,
  70. height: this.originWidth
  71. },
  72. boundStyle: {
  73. color: '#04b00f',
  74. mask: 'rgba(0,0,0,0.8)',
  75. lineWidth: 1
  76. }
  77. },
  78. // 裁剪框和输出图片的尺寸,高度默认等于宽度
  79. // 输出图片宽度,单位px
  80. destWidth: 200,
  81. // 裁剪框宽度,单位px
  82. rectWidth: 200,
  83. // 输出的图片类型,如果'png'类型发现裁剪的图片太大,改成"jpg"即可
  84. fileType: 'jpg',
  85. src: '' // 选择的图片路径,用于在点击确定时,判断是否选择了图片
  86. };
  87. },
  88. onLoad(option) {
  89. let rectInfo = uni.getSystemInfoSync();
  90. this.width = rectInfo.windowWidth;
  91. this.height = rectInfo.windowHeight - this.bottomNavHeight;
  92. this.cropperOpt.width = this.width;
  93. this.cropperOpt.height = this.height;
  94. this.cropperOpt.pixelRatio = rectInfo.pixelRatio;
  95. if (option.destWidth) this.destWidth = Number(option.destWidth);
  96. if (option.rectWidth) {
  97. let rectWidth = Number(option.rectWidth);
  98. this.cropperOpt.cut = {
  99. x: (this.width - rectWidth) / 2,
  100. y: (this.height - rectWidth) / 2,
  101. width: rectWidth,
  102. height: rectWidth
  103. };
  104. }
  105. this.rectWidth = Number(option.rectWidth);
  106. if (option.fileType) this.fileType = option.fileType;
  107. // 初始化
  108. this.cropper = new WeCropper(this.cropperOpt)
  109. .on('ready', ctx => {
  110. // wecropper is ready for work!
  111. })
  112. .on('beforeImageLoad', ctx => {
  113. // before picture loaded, i can do something
  114. })
  115. .on('imageLoad', ctx => {
  116. // picture loaded
  117. })
  118. .on('beforeDraw', (ctx, instance) => {
  119. // before canvas draw,i can do something
  120. });
  121. // 设置导航栏样式,以免用户在page.json中没有设置为黑色背景
  122. uni.setNavigationBarColor({
  123. frontColor: '#ffffff',
  124. backgroundColor: '#000000'
  125. });
  126. uni.chooseImage({
  127. count: 1, // 默认9
  128. sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
  129. sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
  130. success: res => {
  131. this.src = res.tempFilePaths[0];
  132. // 获取裁剪图片资源后,给data添加src属性及其值
  133. this.cropper.pushOrign(this.src);
  134. }
  135. });
  136. },
  137. methods: {
  138. touchStart(e) {
  139. this.cropper.touchStart(e);
  140. },
  141. touchMove(e) {
  142. this.cropper.touchMove(e);
  143. },
  144. touchEnd(e) {
  145. this.cropper.touchEnd(e);
  146. },
  147. getCropperImage(isPre = false) {
  148. if (!this.src) return this.$toast('请先选择图片再裁剪');
  149. let cropper_opt = {
  150. destHeight: Number(this.destWidth), // uni.canvasToTempFilePath要求这些参数为数值
  151. destWidth: Number(this.destWidth),
  152. fileType: this.fileType
  153. };
  154. this.cropper.getCropperImage(cropper_opt, (path, err) => {
  155. if (err) {
  156. uni.showModal({
  157. title: '温馨提示',
  158. content: err.message
  159. });
  160. } else {
  161. if (isPre) {
  162. uni.previewImage({
  163. current: '', // 当前显示图片的 http 链接
  164. urls: [path] // 需要预览的图片 http 链接列表
  165. });
  166. } else {
  167. uni.$emit('Cropper', path);
  168. uni.navigateBack();
  169. }
  170. }
  171. });
  172. },
  173. uploadTap() {
  174. const self = this;
  175. uni.chooseImage({
  176. count: 1, // 默认9
  177. sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
  178. sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
  179. success: res => {
  180. self.src = res.tempFilePaths[0];
  181. // 获取裁剪图片资源后,给data添加src属性及其值
  182. self.cropper.pushOrign(this.src);
  183. }
  184. });
  185. }
  186. }
  187. };
  188. </script>
  189. <style scoped lang="scss">
  190. .content {
  191. background: rgba(255, 255, 255, 1);
  192. }
  193. .cropper {
  194. position: absolute;
  195. top: 0;
  196. left: 0;
  197. width: 100%;
  198. height: 100%;
  199. z-index: 11;
  200. }
  201. .cropper-buttons {
  202. background-color: #000000;
  203. color: #eee;
  204. }
  205. .cropper-wrapper {
  206. position: relative;
  207. display: flex;
  208. flex-direction: row;
  209. justify-content: space-between;
  210. align-items: center;
  211. width: 100%;
  212. background-color: #000;
  213. }
  214. .cropper-buttons {
  215. width: 100vw;
  216. display: flex;
  217. flex-direction: row;
  218. justify-content: space-between;
  219. align-items: center;
  220. position: fixed;
  221. bottom: 0;
  222. left: 0;
  223. padding: 0 20rpx;
  224. box-sizing: border-box;
  225. font-size: 28rpx;
  226. }
  227. .cropper-buttons .upload, .cropper-buttons .getCropperImage{
  228. text-align: center;
  229. }
  230. .btn{
  231. height: 30px;
  232. line-height: 30px;
  233. padding: 0 24rpx;
  234. border-radius: 2px;
  235. color: #ffffff;
  236. }
  237. </style>

2.3、在cropper组件中需要引入we-cropper第三方插件,有两种引入方式

 源码地址:https://github.com/we-plugin/we-cropper/

方式1:npm引入,然后在cropper组件中直接 import WeCropper from 'we-cropper';

方式2:在源码中找到dist文件夹下的we-cropper.js文件,创建utils文件夹,将we-cropper.js文件放入,cropper组件直接引入utils下的

2.4、效果呈现

 

 最后:

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