• uniapp 对上传的图片进行裁剪


    <template>
        <view class="container">
            <view class="page-body uni-content-info">
                <view class='cropper-content'>
                    <view v-if="isShowImg" class="uni-corpper" :style="''+cropperInitW+'px;height:'+cropperInitH+'px;background:#000'">
                        <view class="uni-corpper-content" :style="''+cropperW+'px;height:'+cropperH+'px;left:'+cropperL+'px;top:'+cropperT+'px'">
                            <image :src="imageSrc" :style="''+cropperW+'px;height:'+cropperH+'px'"></image>
                            <view class="uni-corpper-crop-box" @touchstart.stop="contentStartMove" @touchmove.stop="contentMoveing" @touchend.stop="contentTouchEnd"
                                :style="'left:'+cutL+'px;top:'+cutT+'px;right:'+cutR+'px;bottom:'+cutB+'px'">
                                <view class="uni-cropper-view-box">
                                    <view class="uni-cropper-dashed-h"></view>
                                    <view class="uni-cropper-dashed-v"></view>
                                    <view class="uni-cropper-line-t" data-drag="top" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
                                    <view class="uni-cropper-line-r" data-drag="right" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
                                    <view class="uni-cropper-line-b" data-drag="bottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
                                    <view class="uni-cropper-line-l" data-drag="left" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
                                    <view class="uni-cropper-point point-t" data-drag="top" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
                                    <view class="uni-cropper-point point-tr" data-drag="topTight"></view>
                                    <view class="uni-cropper-point point-r" data-drag="right" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
                                    <view class="uni-cropper-point point-rb" data-drag="rightBottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
                                    <view class="uni-cropper-point point-b" data-drag="bottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove" @touchend.stop="dragEnd"></view>
                                    <view class="uni-cropper-point point-bl" data-drag="bottomLeft"></view>
                                    <view class="uni-cropper-point point-l" data-drag="left" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
                                    <view class="uni-cropper-point point-lt" data-drag="leftTop"></view>
                                </view>
                            </view>
                        </view>
                    </view>
                </view>
                <view class='cropper-config'>
                    <button type="primary reverse" @click="getImage" style='margin-top: 30upx;'> 选择图片 </button>
                    <button type="warn" @click="getImageInfo" style='margin-top: 30upx;'> 点击生成图片 </button>
                </view>
                <canvas canvas-id="myCanvas" :style="'position:absolute;border: 1px solid red; '+imageW+'px;height:'+imageH+'px;top:-9999px;left:-9999px;'"></canvas>
            </view>
            <page-foot :name="name"></page-foot>
        </view>
    </template>
     
    <script>
        let sysInfo = uni.getSystemInfoSync();
        let SCREEN_WIDTH = sysInfo.screenWidth
        let PAGE_X, // 手按下的x位置
            PAGE_Y, // 手按下y的位置
            PR = sysInfo.pixelRatio, // dpi
            T_PAGE_X, // 手移动的时候x的位置
            T_PAGE_Y, // 手移动的时候Y的位置
            CUT_L, // 初始化拖拽元素的left值
            CUT_T, // 初始化拖拽元素的top值
            CUT_R, // 初始化拖拽元素的
            CUT_B, // 初始化拖拽元素的
            CUT_W, // 初始化拖拽元素的宽度
            CUT_H, //  初始化拖拽元素的高度
            IMG_RATIO, // 图片比例
            IMG_REAL_W, // 图片实际的宽度
            IMG_REAL_H, // 图片实际的高度
            DRAFG_MOVE_RATIO = 1, //移动时候的比例,
            INIT_DRAG_POSITION = 100, // 初始化屏幕宽度和裁剪区域的宽度之差,用于设置初始化裁剪的宽度
            DRAW_IMAGE_W = sysInfo.screenWidth // 设置生成的图片宽度
     
        export default {
            /**
             * 页面的初始数据
             */
            data() {
                return {
                    name:'杨大宝',
                    imageSrc: 'https://img-cdn-qiniu.dcloud.net.cn/demo_crop.jpg',
                    isShowImg: false,
                    // 初始化的宽高
                    cropperInitW: SCREEN_WIDTH,
                    cropperInitH: SCREEN_WIDTH,
                    // 动态的宽高
                    cropperW: SCREEN_WIDTH,
                    cropperH: SCREEN_WIDTH,
                    // 动态的left top值
                    cropperL: 0,
                    cropperT: 0,
     
                    transL: 0,
                    transT: 0,
     
                    // 图片缩放值
                    scaleP: 0,
                    imageW: 0,
                    imageH: 0,
     
                    // 裁剪框 宽高
                    cutL: 0,
                    cutT: 0,
                    cutB: SCREEN_WIDTH,
                    cutR: '100%',
                    qualityWidth: DRAW_IMAGE_W,
                    innerAspectRadio: DRAFG_MOVE_RATIO
                }
            },
            /**
             * 生命周期函数--监听页面加载
             */
            onLoad: function (options) {},
     
            /**
             * 生命周期函数--监听页面初次渲染完成
             */
            onReady: function () {
     
                this.loadImage();
     
            },
            methods: {
                setData: function (obj) {
                    let that = this;
                    Object.keys(obj).forEach(function (key) {
                        that.$set(that.$data, key, obj[key])
     
                    });
                },
                getImage: function () {
                    var _this = this
                    uni.chooseImage({
                        success: function (res) {
                            _this.setData({
                                imageSrc: res.tempFilePaths[0],
                            })
                            _this.loadImage();
                        },
                    })
                },
                loadImage: function () {
                    var _this = this
                    uni.showLoading({
                        title: '图片加载中...',
                    })
     
                    uni.getImageInfo({
                        src: _this.imageSrc,
                        success: function success(res) {
                            IMG_RATIO = res.width / res.height
                            if (IMG_RATIO >= 1) {
                                IMG_REAL_W = SCREEN_WIDTH
                                IMG_REAL_H = SCREEN_WIDTH / IMG_RATIO
                            } else {
                                IMG_REAL_W = SCREEN_WIDTH * IMG_RATIO
                                IMG_REAL_H = SCREEN_WIDTH
                            }
                            let minRange = IMG_REAL_W > IMG_REAL_H ? IMG_REAL_W : IMG_REAL_H
                            INIT_DRAG_POSITION = minRange > INIT_DRAG_POSITION ? INIT_DRAG_POSITION : minRange
                            // 根据图片的宽高显示不同的效果   保证图片可以正常显示
                            if (IMG_RATIO >= 1) {
                                let cutT = Math.ceil((SCREEN_WIDTH / IMG_RATIO - (SCREEN_WIDTH / IMG_RATIO - INIT_DRAG_POSITION)) / 2);
                                let cutB = cutT;
                                let cutL = Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH + INIT_DRAG_POSITION) / 2);
                                let cutR = cutL;
                                _this.setData({
                                    cropperW: SCREEN_WIDTH,
                                    cropperH: SCREEN_WIDTH / IMG_RATIO,
                                    // 初始化left right
                                    cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2),
                                    cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO) / 2),
                                    cutL: cutL,
                                    cutT: cutT,
                                    cutR: cutR,
                                    cutB: cutB,
                                    // 图片缩放值
                                    imageW: IMG_REAL_W,
                                    imageH: IMG_REAL_H,
                                    scaleP: IMG_REAL_W / SCREEN_WIDTH,
                                    qualityWidth: DRAW_IMAGE_W,
                                    innerAspectRadio: IMG_RATIO
                                })
                            } else {
                                let cutL = Math.ceil((SCREEN_WIDTH * IMG_RATIO - (SCREEN_WIDTH * IMG_RATIO)) / 2);
                                let cutR = cutL;
                                let cutT = Math.ceil((SCREEN_WIDTH - INIT_DRAG_POSITION) / 2);
                                let cutB = cutT;
                                _this.setData({
                                    cropperW: SCREEN_WIDTH * IMG_RATIO,
                                    cropperH: SCREEN_WIDTH,
                                    // 初始化left right
                                    cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO) / 2),
                                    cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2),
     
                                    cutL: cutL,
                                    cutT: cutT,
                                    cutR: cutR,
                                    cutB: cutB,
                                    // 图片缩放值
                                    imageW: IMG_REAL_W,
                                    imageH: IMG_REAL_H,
                                    scaleP: IMG_REAL_W / SCREEN_WIDTH,
                                    qualityWidth: DRAW_IMAGE_W,
                                    innerAspectRadio: IMG_RATIO
                                })
                            }
                            _this.setData({
                                isShowImg: true
                            })
                            uni.hideLoading()
                        }
                    })
                },
                // 拖动时候触发的touchStart事件
                contentStartMove(e) {
                    PAGE_X = e.touches[0].pageX
                    PAGE_Y = e.touches[0].pageY
                },
     
                // 拖动时候触发的touchMove事件
                contentMoveing(e) {
                    var _this = this
                    var dragLengthX = (PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
                    var dragLengthY = (PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
                    // 左移
                    if (dragLengthX > 0) {
                        if (this.cutL - dragLengthX < 0) dragLengthX = this.cutL
                    } else {
                        if (this.cutR + dragLengthX < 0) dragLengthX = -this.cutR
                    }
     
                    if (dragLengthY > 0) {
                        if (this.cutT - dragLengthY < 0) dragLengthY = this.cutT
                    } else {
                        if (this.cutB + dragLengthY < 0) dragLengthY = -this.cutB
                    }
                    this.setData({
                        cutL: this.cutL - dragLengthX,
                        cutT: this.cutT - dragLengthY,
                        cutR: this.cutR + dragLengthX,
                        cutB: this.cutB + dragLengthY
                    })
     
                    PAGE_X = e.touches[0].pageX
                    PAGE_Y = e.touches[0].pageY
                },
     
                contentTouchEnd() {
     
                },
     
                // 获取图片
                getImageInfo() {
                    var _this = this;
                    uni.showLoading({
                        title: '图片生成中...',
                    });
                    // 将图片写入画布
                    const ctx = uni.createCanvasContext('myCanvas');
                    ctx.drawImage(_this.imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H);
                    ctx.draw(true, () => {
                        // 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题 canvasT = (_this.cutT / _this.cropperH) * (_this.imageH / pixelRatio)
                        var canvasW = ((_this.cropperW - _this.cutL - _this.cutR) / _this.cropperW) * IMG_REAL_W;
                        var canvasH = ((_this.cropperH - _this.cutT - _this.cutB) / _this.cropperH) * IMG_REAL_H;
                        var canvasL = (_this.cutL / _this.cropperW) * IMG_REAL_W;
                        var canvasT = (_this.cutT / _this.cropperH) * IMG_REAL_H;
                        uni.canvasToTempFilePath({
                            x: canvasL,
                            y: canvasT,
                             canvasW,
                            height: canvasH,
                            destWidth: canvasW,
                            destHeight: canvasH,
                            quality: 0.5,
                            canvasId: 'myCanvas',
                            success: function (res) {
                                uni.hideLoading()
                                // 成功获得地址的地方
                                uni.previewImage({
                                    current: '', // 当前显示图片的http链接
                                    urls: [res.tempFilePath] // 需要预览的图片http链接列表
                                })
                            }
                        });
                    });
                },
     
                // 设置大小的时候触发的touchStart事件
                dragStart(e) {
                    T_PAGE_X = e.touches[0].pageX
                    T_PAGE_Y = e.touches[0].pageY
                    CUT_L = this.cutL
                    CUT_R = this.cutR
                    CUT_B = this.cutB
                    CUT_T = this.cutT
                },
     
                // 设置大小的时候触发的touchMove事件
                dragMove(e) {
                    var _this = this
                    var dragType = e.target.dataset.drag
                    switch (dragType) {
                        case 'right':
                            var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
                            if (CUT_R + dragLength < 0) dragLength = -CUT_R
                            this.setData({
                                cutR: CUT_R + dragLength
                            })
                            break;
                        case 'left':
                            var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
                            if (CUT_L - dragLength < 0) dragLength = CUT_L
                            if ((CUT_L - dragLength) > (this.cropperW - this.cutR)) dragLength = CUT_L - (this.cropperW - this.cutR)
                            this.setData({
                                cutL: CUT_L - dragLength
                            })
                            break;
                        case 'top':
                            var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
                            if (CUT_T - dragLength < 0) dragLength = CUT_T
                            if ((CUT_T - dragLength) > (this.cropperH - this.cutB)) dragLength = CUT_T - (this.cropperH - this.cutB)
                            this.setData({
                                cutT: CUT_T - dragLength
                            })
                            break;
                        case 'bottom':
                            var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
                            if (CUT_B + dragLength < 0) dragLength = -CUT_B
                            this.setData({
                                cutB: CUT_B + dragLength
                            })
                            break;
                        case 'rightBottom':
                            var dragLengthX = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
                            var dragLengthY = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
     
                            if (CUT_B + dragLengthY < 0) dragLengthY = -CUT_B
                            if (CUT_R + dragLengthX < 0) dragLengthX = -CUT_R
                            let cutB = CUT_B + dragLengthY;
                            let cutR = CUT_R + dragLengthX;
     
                            this.setData({
                                cutB: cutB,
                                cutR: cutR
                            })
                            break;
                        default:
                            break;
                    }
                }
            }
        }
    </script>
     
    <style>
        /* pages/uni-cropper/index.wxss */
     
        .uni-content-info {
            /* position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            display: block;
            align-items: center;
            flex-direction: column; */
        }
     
        .cropper-config {
            padding: 20upx 40upx;
        }
     
        .cropper-content {
            min-height: 750upx;
             100%;
        }
     
        .uni-corpper {
            position: relative;
            overflow: hidden;
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
            -webkit-tap-highlight-color: transparent;
            -webkit-touch-callout: none;
            box-sizing: border-box;
        }
     
        .uni-corpper-content {
            position: relative;
        }
     
        .uni-corpper-content image {
            display: block;
             100%;
            min- 0 !important;
            max- none !important;
            height: 100%;
            min-height: 0 !important;
            max-height: none !important;
            image-orientation: 0deg !important;
            margin: 0 auto;
        }
        /* 移动图片效果 */
     
        .uni-cropper-drag-box {
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            cursor: move;
            background: rgba(0, 0, 0, 0.6);
            z-index: 1;
        }
        /* 内部的信息 */
     
        .uni-corpper-crop-box {
            position: absolute;
            background: rgba(255, 255, 255, 0.3);
            z-index: 2;
        }
     
        .uni-corpper-crop-box .uni-cropper-view-box {
            position: relative;
            display: block;
             100%;
            height: 100%;
            overflow: visible;
            outline: 1upx solid #69f;
            outline-color: rgba(102, 153, 255, .75)
        }
        /* 横向虚线 */
     
        .uni-cropper-dashed-h {
            position: absolute;
            top: 33.33333333%;
            left: 0;
             100%;
            height: 33.33333333%;
            border-top: 1upx dashed rgba(255, 255, 255, 0.5);
            border-bottom: 1upx dashed rgba(255, 255, 255, 0.5);
        }
        /* 纵向虚线 */
     
        .uni-cropper-dashed-v {
            position: absolute;
            left: 33.33333333%;
            top: 0;
             33.33333333%;
            height: 100%;
            border-left: 1upx dashed rgba(255, 255, 255, 0.5);
            border-right: 1upx dashed rgba(255, 255, 255, 0.5);
        }
        /* 四个方向的线  为了之后的拖动事件*/
     
        .uni-cropper-line-t {
            position: absolute;
            display: block;
             100%;
            
            top: 0;
            left: 0;
            height: 1upx;
            opacity: 0.1;
            cursor: n-resize;
        }
     
        .uni-cropper-line-t::before {
            content: '';
            position: absolute;
            top: 50%;
            right: 0upx;
             100%;
            -webkit-transform: translate3d(0, -50%, 0);
            transform: translate3d(0, -50%, 0);
            bottom: 0;
            height: 41upx;
            background: transparent;
            z-index: 11;
        }
     
        .uni-cropper-line-r {
            position: absolute;
            display: block;
            
            top: 0;
            right: 0upx;
             1upx;
            opacity: 0.1;
            height: 100%;
            cursor: e-resize;
        }
     
        .uni-cropper-line-r::before {
            content: '';
            position: absolute;
            top: 0;
            left: 50%;
             41upx;
            -webkit-transform: translate3d(-50%, 0, 0);
            transform: translate3d(-50%, 0, 0);
            bottom: 0;
            height: 100%;
            background: transparent;
            z-index: 11;
        }
     
        .uni-cropper-line-b {
            position: absolute;
            display: block;
             100%;
            
            bottom: 0;
            left: 0;
            height: 1upx;
            opacity: 0.1;
            cursor: s-resize;
        }
     
        .uni-cropper-line-b::before {
            content: '';
            position: absolute;
            top: 50%;
            right: 0upx;
             100%;
            -webkit-transform: translate3d(0, -50%, 0);
            transform: translate3d(0, -50%, 0);
            bottom: 0;
            height: 41upx;
            background: transparent;
            z-index: 11;
        }
     
        .uni-cropper-line-l {
            position: absolute;
            display: block;
            
            top: 0;
            left: 0;
             1upx;
            opacity: 0.1;
            height: 100%;
            cursor: w-resize;
        }
     
        .uni-cropper-line-l::before {
            content: '';
            position: absolute;
            top: 0;
            left: 50%;
             41upx;
            -webkit-transform: translate3d(-50%, 0, 0);
            transform: translate3d(-50%, 0, 0);
            bottom: 0;
            height: 100%;
            background: transparent;
            z-index: 11;
        }
     
        .uni-cropper-point {
             5upx;
            height: 5upx;
            
            opacity: .75;
            position: absolute;
            z-index: 3;
        }
     
        .point-t {
            top: -3upx;
            left: 50%;
            margin-left: -3upx;
            cursor: n-resize;
        }
     
        .point-tr {
            top: -3upx;
            left: 100%;
            margin-left: -3upx;
            cursor: n-resize;
        }
     
        .point-r {
            top: 50%;
            left: 100%;
            margin-left: -3upx;
            margin-top: -3upx;
            cursor: n-resize;
        }
     
        .point-rb {
            left: 100%;
            top: 100%;
            -webkit-transform: translate3d(-50%, -50%, 0);
            transform: translate3d(-50%, -50%, 0);
            cursor: n-resize;
             36upx;
            height: 36upx;
            
            position: absolute;
            z-index: 1112;
            opacity: 1;
        }
     
        .point-b {
            left: 50%;
            top: 100%;
            margin-left: -3upx;
            margin-top: -3upx;
            cursor: n-resize;
        }
     
        .point-bl {
            left: 0%;
            top: 100%;
            margin-left: -3upx;
            margin-top: -3upx;
            cursor: n-resize;
        }
     
        .point-l {
            left: 0%;
            top: 50%;
            margin-left: -3upx;
            margin-top: -3upx;
            cursor: n-resize;
        }
     
        .point-lt {
            left: 0%;
            top: 0%;
            margin-left: -3upx;
            margin-top: -3upx;
            cursor: n-resize;
        }
        /* 裁剪框预览内容 */
     
        .uni-cropper-viewer {
            position: relative;
             100%;
            height: 100%;
            overflow: hidden;
        }
     
        .uni-cropper-viewer image {
            position: absolute;
            z-index: 2;
        }
    </style>

    来源:https://www.cnblogs.com/cfcastiel/articles/14470188.html

  • 相关阅读:
    Combine 框架,从0到1 —— 4.在 Combine 中使用计时器
    Combine 框架,从0到1 —— 4.在 Combine 中使用通知
    Combine 框架,从0到1 —— 3.使用 Subscriber 控制发布速度
    Combine 框架,从0到1 —— 2.通过 ConnectablePublisher 控制何时发布
    使用 Swift Package Manager 集成依赖库
    iOS 高效灵活地配置可复用视图组件的主题
    构建个人博客网站(基于Python Flask)
    Swift dynamic关键字
    Swift @objcMembers
    仅用递归函数操作逆序一个栈(Swift 4)
  • 原文地址:https://www.cnblogs.com/brillant/p/15507955.html
Copyright © 2020-2023  润新知