uni-app 最新HX版本使用画布裁切图片问题

uni-app 最新HX版本使用画布裁切图片问题

产品分类 PC开发环境操作系统 PC开发环境操作系统版本号 HBuilderX版本号
HbuilderX Windows windows 10 20H2 3.1.2
## 示例代码:

怕你们复现麻烦,再贴完整代码。
下为cropper.vue和调用方法,vue文件需在pages.json里面注册,我这里是 '/pages/view/tools/cropper'
we-cropper地址,同目录存放,https://github.com/we-plugin/we-cropper/blob/master/dist/we-cropper.js
这个裁切文件实现了一些实用的功能:自定义尺寸裁切,批量自动裁切,手动裁切,及自动生成两级缩略图,需要可以拿去用。

``` vue
<template>  
    <view style="height:100vh;overflow: hidden;">  
        <view class="cropper-wrapper" :style="{ height: cropperOpt.height + 'px',opacity: show?1:0 }">  
            <canvas type="2d" class="cropper" :disable-scroll="true" @touchstart="touchStart"  
             @touchmove="touchMove" @touchend="touchEnd" :style="{   
                 width: cropperOpt.width,   
                 height: cropperOpt.height,   
                 backgroundColor: 'rgba(0, 0, 0, 0.8)' }"  
             canvas-id="cropper" id="cropper" @click="preview()">  
            </canvas>  
            <canvas type="2d" class="cropper" :disable-scroll="true" :style="{  
                    top: `-${cropperOpt.width * cropperOpt.pixelRatio}px`,  
                    left: `-${cropperOpt.height * cropperOpt.pixelRatio}px`,  
                    width: `${cropperOpt.width * cropperOpt.pixelRatio}px`,  
                    height: `${cropperOpt.height * cropperOpt.pixelRatio}px`,  
                }"  
             canvas-id="targetId" id="targetId">  
            </canvas>  
        </view>  
        <ff-button v-if="show" right="完成" :left="src?'重新选择':'选择图片'" @clickR="submit"  
         @clickL="select">  
        </ff-button>  
    </view>  
</template> 
<script>  
    import WeCropper from './weCropper.js';  
    export default {  
        props: {  
            boundStyle: {  
                type: Object,  
                default () {  
                    return {  
                        lineWidth: 2,  
                        borderColor: 'rgba(0, 255, 0, 0.8)',  
                        mask: 'rgba(0, 0, 0, 0.5)'  
                    }  
                }  
            }  
        },  
        data() {  
            return {  
                // 底部导航的高度  
                bottomNavHeight: 40,  
                cropperOpt: {  
                    id: 'cropper',  
                    targetId: 'targetId',  
                    pixelRatio: 1,  
                    scale: 2.5,  
                    zoom: 5,  
                    width: 0,  
                    height: 0,  
                    boundStyle: {  
                        lineWidth: this.boundStyle.lineWidth,  
                        mask: this.boundStyle.mask,  
                        color: this.boundStyle.borderColor  
                    },  
                    cut: { x: 200, y: 200, width: 200, height: 200 }  
                },  
                destWidth: 200,  
                destHeight: 200,  
                src: null,  
                ops: null,  
                show: false,  
                cropper: null,  
            }  
        },  
        onLoad(ops) {  
            this.ops = ops  
            if (!ops.cropper)  
                this.ops.cropper = 'manual'  
            this.show = ops.cropper == 'manual'  
            uni.setNavigationBarColor({  
                frontColor: '#ffffff',  
                backgroundColor: '#000000'  
            })  
            if (!this.show) {  
                this.bottomNavHeight = 0  
                uni.setNavigationBarTitle({ title: '选择图片' })  
            }  

            let device = uni.getSystemInfoSync()  
            this.width = device.windowWidth  
            this.height = device.windowHeight  

            this.cropperOpt.width = this.width  
            this.cropperOpt.height = this.height - this.bottomNavHeight  

            this.cropperOpt.pixelRatio = device.pixelRatio  

            if (ops.width && ops.height) {  
                this.destWidth = +ops.width  
                this.destHeight = +ops.height  
                this.cropperOpt.cut = {  
                    x: (this.width - +ops.width) / 2,  
                    y: (this.height - +ops.height) / 2,  
                    width: +ops.width,  
                    height: +ops.height  
                }  
            }  
            this.cropper = new WeCropper(this.cropperOpt)  
            this.select()  
        },  
        methods: {  
            async select() {  
                this.src = await this.chooseImage(+this.ops.count || 1)  
                if (this.ops.cropper == 'auto') {  
                    uni.showLoading({ title: '裁切中' })  
                    let result = await this.autoCompressed()  
                    uni.$emit('cropper', result)  
                    uni.hideLoading()  
                    uni.navigateBack()  
                } else if (this.ops.cropper == 'manual') {  
                    await this.cropper.pushOrign(this.src[0])  
                } else {  
                    uni.$emit('cropper', this.src)  
                    uni.navigateBack()  
                }  

            },  
            async submit() {  
                let result = []  
                let tmp = await this.getCropperImage()  
                result.push(tmp)  
                if (this.ops.thumbnail) {  
                    let thumbnail = await this.createThumbnail()  
                    result = result.concat(thumbnail)  
                }  
                uni.$emit('cropper', result)  
                uni.navigateBack()  
            },  
            async preview() {  
                let result = await this.getCropperImage()  
                uni.previewImage({ urls: [result] })  
            },  
            getCropperImage(scale = 1) {  
                return this.cropper.getCropperImage({  
                    destWidth: this.destWidth / scale,  
                    destHeight: this.destHeight / scale,  
                    fileType: this.ops.fileType || 'jpg',  
                    // original: true  
                })  
            },  

            async createThumbnail() {  
                let thumb_m = await this.getCropperImage(2)  
                let thumb_s = await this.getCropperImage(4)  
                return [thumb_m, thumb_s]  
            },  

            async autoCompressed() {  
                let path = []  
                for (let i = 0; i < this.src.length; i++) {  
                    await this.cropper.pushOrign(this.src[i])  
                    path[i] = await this.getCropperImage()  
                }  
                return path  
            },  

            touchStart(e) { this.cropper.touchStart(e) },  
            touchMove(e) { this.cropper.touchMove(e) },  
            touchEnd(e) { this.cropper.touchEnd(e) },  

            chooseImage(count) {  
                return new Promise((resolve, reject) => {  
                    uni.chooseImage({  
                        count,  
                        sizeType: ['compressed'],  
                        sourceType: ['album'],  
                        success: res => resolve(res.tempFilePaths),  
                        fail: err => reject(err)  
                    })  
                })  
            },  
        }  
    }  
</script> 
<style scoped>  
    .cropper {  
        position: absolute;  
        top: 0;  
        left: 0;  
        width: 100%;  
        height: 100%;  
        z-index: 2;  
        ;  
    }  

    .cropper-wrapper {  
        position: relative;  
        display: flex;  
        justify-content: space-between;  
        align-items: center;  
        /* height: 100%; */  
        width: 100%;  
        background-color: #949494;  
    }  
</style>

调用代码,其他文件里面方法调用。

chooseImage() {  
    uni.$on('cropper', path => {  
        uni.$off('cropper')  
        this.oldbg.push(this.module.image)  
        this.$set(this.module, 'image', path[0])  
        this.disabled = false  
    })  
    let width = uni.getSystemInfoSync().windowWidth  
    this.$u.route('/pages/view/tools/cropper', {  
        width: width,  
        height: width * 4 / 3  
    })  
}

操作步骤:

问题复现,需要调用we-cropper插件,给到目标宽高尺寸,且高度大于屏幕宽度。 一、引入https://github.com/we-plugin/we-cropper插件 二、按上面的布局代码,给到目标高宽尺寸,然后获取裁切结果。 三、HX最新版本的H5,返回的图片会被拉伸,其他版本或小程序版本没有问题。

预期结果:

按照目标尺寸裁切,返回图片。

实际结果:

按照目标尺寸裁切,返回图片,尺寸没问题,但被拉伸了。

bug描述:

使用 https://github.com/we-plugin/we-cropper 裁切画布,当目标高度大于屏幕宽度时,会返回目标高度尺寸的图片,但图片会进行拉伸,!!!bug在图片拉伸这里!!! 一、只最新版的H5中会出现,小程序中没问题。 二、只在3.1.2.20210206版本中出现,其他版本没问题。 三、we-cropper插件没有问题,检查了一天一夜。 四、具体造成bug的原因,查找了很久无果,之后切换回上一版本,没事了。 五、看了最新版本的变动,没有涉及H5编译变动或画布接口变动之类相关更新,苦苦无果,只得来提交bug,否则,无法再用最新版本。


更多关于uni-app 最新HX版本使用画布裁切图片问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

7 回复

调用方法的代码使用了uview-ui的route方法,不用使用uview-ui的方式为:
chooseImage() {
uni.$on(‘cropper’, path => {
uni.$off(‘cropper’)
this.oldbg.push(this.module.image)
this.$set(this.module, ‘image’, path[0])
this.disabled = false
})
let width = uni.getSystemInfoSync().windowWidth

            uni.navigateTo({  
                url: `/pages/view/tools/cropper?width=${width}&height=${width*4/3}`  
            })  
        },<br>

更多关于uni-app 最新HX版本使用画布裁切图片问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html


还有ff-button插件,替换为uni的button就行。

问题已确认,已加分,下版修复

https://ask.dcloud.net.cn/question/117220 应该是一样的bug,最新版设计到了uni.canvasToTempFilePath接口,估计是有关系的

回复 choin: 已回复

HBuilderX 3.1.3 alpha 已修复

多谢!

回到顶部