第一步:拿到图片信息

第二步:计算基准框大小,设置预览图片基准值

第三步:预览图片宽高处理

第四步:获取屏幕宽高,绘制蒙层

第五步:图片预览

第六步:预览图拖拽处理

第七步:图像裁剪

<template><view class="settingHeadImage" @touchstart="onTouchstart" @touchmove.stop.prevent="onTouchmove" @touchend="touchE"><!-- 蒙层 --><canvas class="pre-canvas" canvas-id="firstCanvas" :style="{ width: 100 + 'vw', height: 100 + 'vh' }"></canvas><!-- img预览 --><view class="preImage" :style="{ width: preImgW + 'px' }"><canvas canvas-id="mycanvas" class="pre-i":style="{ width: preImgW + 'px', height: preImgH + 'px', transform: `translate(${x}px,${y}px)` }"></canvas></view><!-- 工具 --><view class="setting-btns"><text @click="onCrop">确定</text></view></view>
</template><script>export default {data() {return {maxW: 250, // 最大宽度maxH: 250,screenWidth: '', // 屏幕宽screenHeight: '',xToTop: 0, // x方向距离顶部距离scale: 1, // 缩放preSrc: '',preImgW: '',preImgH: '',x: 0,y: 0,oldx: 0,oldy: 0,isMove: false,start: {left: 0,top: 0}};},computed: {},onLoad(option) {// 选择照片信息let data = JSON.parse(decodeURIComponent(option.item));const query = uni.createSelectorQuery();query.select('.settingHeadImage').boundingClientRect();query.exec(res => {// 设置屏幕大小this.screenWidth = res[0].width;this.screenHeight = res[0].height;// 设置图像基准值,图像基准值按屏幕宽度设置,两边留白各40this.maxH = res[0].width - 80;this.maxW = res[0].width - 80;// 设置X轴值,算式:屏幕高度的一半减去基准框高度的一半this.xToTop = this.screenHeight / 2 - this.maxH / 2;this.setImageSize(data);});},methods: {// 宽高处理setImageSize(data) {const {tempFilePath} = data;const {maxH,maxW} = this;uni.getImageInfo({src: tempFilePath,success: res => {const {errMsg,path,width,height} = res;let w = '';let h = '';if (errMsg === 'getImageInfo:ok') {w = width;h = height;// 宽大与高大于最大宽度if (width > height && width > maxW) {w = Math.floor((width / height) * maxW);h = maxH;}// 高大于宽大于最大高度if (height > width && height > maxH) {h = Math.floor((height / width) * maxH);w = maxW;}// 宽高相等或者宽高小于最大值if (width === height || (width < maxW && height < maxH)) {h = maxH;w = maxW;}this.preSrc = path;this.preImgH = h;this.preImgW = w;// 设置蒙层this.setBgBox();// 图像预览this.previewCanvas({w,h,path});}}});},// 设置蒙层setBgBox() {const {maxW,maxH,screenHeight,screenWidth,xToTop} = this;const ctx = uni.createCanvasContext('firstCanvas');// 先清除矩形ctx.clearRect(0, 0, screenWidth, screenHeight);// 设置canvas透明度ctx.setGlobalAlpha(0.7);// 设置蒙层颜色ctx.setFillStyle('#000000');// 绘制蒙层ctx.fillRect(0, 0, screenWidth, screenHeight);// 基准框留白ctx.clearRect(40, xToTop, maxW, maxH);// 绘制基准框ctx.beginPath();ctx.setStrokeStyle('#FFFFFF');ctx.strokeRect(40, xToTop, maxW, maxH);ctx.closePath();ctx.draw();},// 预览previewCanvas({w,h,path}) {const ctx = uni.createCanvasContext('mycanvas');ctx.drawImage(path, 0, 0, w, h);ctx.draw();},onTouchstart(ev) {if (ev.changedTouches.length === 1) {this.isMove = true;this.start.left = ev.changedTouches[0].clientX;this.start.top = ev.changedTouches[0].clientY;}},onTouchmove(ev) {const {maxW,maxH,preImgH,preImgW,xToTop} = this;if (this.isMove && ev.changedTouches.length === 1) {let clientX = ev.changedTouches[0].clientX,clientY = ev.changedTouches[0].clientY;this.x = preImgW <= maxW ? 0 : this.oldx + clientX - this.start.left;this.y = preImgH <= maxH ? 0 : this.oldy + clientY - this.start.top;}},touchE(val) {const {preImgH,preImgW,maxH,maxW} = this;const query = uni.createSelectorQuery();const fx = this.x;query.select('.pre-i').boundingClientRect();query.exec(res => {// x、y回弹计算let y = (res[0].height - res[0].width) / 2;/*** 判断照片可移动的距离是否大于留白的值,如果大于向右划时图片的宽减去基准框的宽减去留白向左时留白,小于时按图片的可移动值* */ let x = (preImgW - maxW) / 2 > 40 ? (fx < 0 ? preImgW - maxW - 40 : 40) : (preImgW - maxW) / 2;if (preImgH > maxH) {this.y = this.y > y ? y : this.y < -y ? -y : this.y;}if (preImgW > maxW) {this.x = this.x > x ? x : this.x < -x ? -x : this.x;}this.oldx = this.x;this.oldy = this.y;this.isMove = false;});},// 裁剪onCrop() {let y = 0;let x = 0;const query = uni.createSelectorQuery();query.select('.pre-i').boundingClientRect();query.exec(res => {// 获取预览img距离左上的距离y = Math.abs(res[0].top);x = Math.abs(res[0].left);const {maxW,maxH,preImgH,preImgW,xToTop} = this;uni.canvasToTempFilePath({x: Math.abs(res[0].left < 0 ? x + 40 : x - 40),y: Math.abs(res[0].top < 0 ? xToTop + y : xToTop - y),width: maxW,height: maxH,destWidth: maxW,destHeight: maxH,canvasId: 'mycanvas',success: fileRes => {console.log(fileRes);uni.previewImage({count: 1,urls: [fileRes.tempFilePath]});},fail: function(err) {console.log(err);uni.showToast({title: '上传失败:图片生成过程中遇到错误',icon: 'none'});}});});}}};
</script><style lang="scss" scoped>.settingHeadImage {background-color: #000000;overflow: hidden;.pre-canvas {position: fixed;top: 0;left: 0;z-index: 20;}.preImage {min-width: 100vw;height: 100vh;display: flex;justify-content: center;align-items: center;overflow: hidden;z-index: 1;.pre-i {// transition: all 0.1s;}}.setting-btns {position: fixed;bottom: 0;left: 0;z-index: 20;font-size: 14px;color: #ffffff;}}
</style>

uniapp图像裁剪相关推荐

  1. canvas实现图像裁剪

    1.技术背景 随着都市类程序开发业务推进,在各类活动.个人信息等模块逐渐依赖图像裁剪.上传等功能,那么如何实现图像缩放.裁剪就成了前端工程师们关注优化的重点. 2.应用技术 本次使用的技术主要是依赖c ...

  2. java图像处理之图像裁剪

    图像裁剪即截取原始图像某一部分生成一幅新的图像,某些app也会要求用户将上传图像进行一定程度裁剪来作为头像.图像裁剪实现起来比较简单,下面介绍两种裁剪方式,矩形裁剪和圆形裁剪. 矩形裁剪,定义图像上某 ...

  3. jQuery 图像裁剪插件Jcrop

    Jcrop简介 Jcrop 是一个功能强大的 jQuery 图像裁剪插件,结合后端程序(例如:PHP)可以快速的实现图片裁剪的功能. Jcrop是一款免费的软件,采用MIT License发布. 注: ...

  4. html图片自动剪裁,HTML canvas图像裁剪

    canvas drawImage方法的图像裁剪理解可能会比较耗时,记录一下,以便供人翻阅! context.drawImage(img,sx,sy,swidth,sheight,x,y,width,h ...

  5. 3h精通OpenCV(三)-重调大小与图像裁剪

    0.准备工作 右击新建的项目,选择Python File,新建一个Python文件,然后在开头import cv2导入cv2库. 我们还要知道在OpenCV中,坐标轴的方向是x轴向右,y轴向下,坐标原 ...

  6. ENVI5.3.1使用Landsat 8影像进行图像镶嵌和图像裁剪实例操作

    数据介绍及数据其他操作详见此博客 ENVI5.3.1使用Landsat 8影像进行预处理及分析实例操作 数据介绍参看这篇博客 ENVI5.3.1使用Landsat 8影像进行辐射定标和大气校正实例操作 ...

  7. 地图裁剪器,可以将图片裁剪成瓦片数据,主要用途是将高清卫星图像裁剪成瓦片图,可以做离线地图的开发,基于墨卡托坐标

    废话不多说,直接上代码 地图裁剪器,可以将图片裁剪成瓦片数据,主要用途是将高清卫星图像裁剪成瓦片图,可以做离线地图的开发,基于墨卡托坐标 地图裁剪 package com.wwp.utils.map; ...

  8. vue 移动端头像裁剪_vue头像上传裁剪组件_一个漂亮的Vue组件,用于图像裁剪和上传...

    vue头像上传裁剪组件 vue-image-crop-upload (vue-image-crop-upload) A beautiful vue component for image crop a ...

  9. 【ENVI入门系列】10.图像裁剪

    [ENVI入门系列]10.图像裁剪 (2014-09-26 10:08:15) 转载▼ 标签: 杂谈 分类: ENVI 版权声明:本教程涉及到的数据仅供练习使用,禁止用于商业用途. 目录 图像裁剪 1 ...

最新文章

  1. 19个语法助你打牢Python基础
  2. 为什么 Java 线程没有 Running 状态?一下被问懵!
  3. CentOS7下的Django2集成部署五:Jenkins的流水线部署pipeline-job
  4. 项目管理实战之团队管理 (转)
  5. mysql里b树_MySQL-B树/B+树
  6. Python 进阶之路 (十) 再立Flag, 社区最全的itertools深度解析(中)
  7. MATLAB判断矩阵相等
  8. Map 和 WeakMap
  9. 微软低代码工具 Power Apps 配置不当,暴露3800万条数据记录
  10. hashmap扩容_我说我了解集合类,面试官竟然问我为啥HashMap的负载因子不设置成1!?
  11. 汇编语言程序设计的实验环境及上机步骤
  12. Ubuntu 11.04下thrift-0.8.0的安装 - Linux - 红黑联盟
  13. 2017 Multi-University Training Contest - Team 10
  14. 美国硕士计算机机械专业排名,工科“三巨头”之一-机械工程的美国硕士申请全解答...
  15. netlink使用方法
  16. PostgreSQL插入大量数据:pg_testgen插件
  17. 学生使用计算机注意事项有哪些,购买笔记本有哪些注意事项?学生购买笔记本八项注意...
  18. 计算机信息安全及保密,计算机信息安全与保密.ppt
  19. Python总纲路线
  20. Android 替换原生输入法

热门文章

  1. tensorflow系列——读取tfrecord数据
  2. 算法刷刷刷|二叉树篇|二叉树的遍历
  3. SpringBoot入门案例
  4. 2023-07-13 Fitz完成PDF转TXT
  5. 设计思想学习—装饰者模式
  6. MATLAB 进度条
  7. 破解电信的星空极速绑定
  8. lmx6q开发板android,迅为I.MX6Q开发板配不同分辨率不同尺寸液晶屏幕
  9. nginx实现数据库端口转发
  10. office2019安装