2***@qq.com
2***@qq.com
  • 发布:2025-06-16 18:45
  • 更新:2025-06-16 18:45
  • 阅读:44

【报Bug】iOS端, 调用 chooseImage API 选择半透明图, 获取到的图片是24位深的图片, 没有透明度

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: 10.0.19045

HBuilderX类型: 正式

HBuilderX版本号: 4.66

手机系统: iOS

手机系统版本号: iOS 16

手机厂商: 苹果

手机机型: iPhone 8

页面类型: vue

vue版本: vue3

打包方式: 云端

项目创建方式: HBuilderX

示例代码:
<template>  
    <view>  
        <button type="primary" @click="chooseImage">选择图片</button>  
        <canvas canvas-id="canvas" ref="canvas" class="canvas" :data-image="imageSrc" :start="startStatus" :change:start="animate.start"  
            :touch="touchOperation" :change:touch="animate.onMessage" :data-width="canvasWidth"  
            :data-height="canvasWidth" @touchstart="onTouchStart" @touchmove="onTouchMove" @touchend="onTouchEnd" />  
    </view>  
</template>  

<script module="animate" lang="renderjs">  
    function Ball({  
        x,  
        y,  
        vx,  
        vy,  
        canvasWidth,  
        canvasHeight,  
        ctx  
    }) {  
        this.x = x  
        this.y = y  
        this.vx = vx  
        this.vy = vy  
        this.canvasWidth = canvasWidth  
        this.canvasHeight = canvasHeight  
        this.ctx = ctx  
        this.radius = 5  
    }  

    Ball.prototype.draw = function() {  
        this.ctx.beginPath()  
        this.ctx.fillStyle = '#007AFF'  
        this.ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI)  
        this.ctx.closePath()  
        this.ctx.fill()  
    }  

    Ball.prototype.move = function() {  
        this.x += this.vx  
        this.y += this.vy  
        if (this.x < this.radius || this.x > this.canvasWidth - this.radius) {  
            this.vx *= -1  
        }  
        if (this.y < this.radius || this.y > this.canvasHeight - this.radius) {  
            this.vy *= -1  
        }  
    }  

    function getDistance(x, y) {  
        return Math.sqrt(x * x + y * y)  
    }  

    export default {  
        mounted() {  
            this.dragging = false  
            this.imgState = {  
                x: 50,  
                y: 50,  
                width: 100,  
                height: 100,  
                offsetX: 0,  
                offsetY: 0  
            }  
        },  
        methods: {  
            start(newVal, oldVal, owner, ins) {  
                const canvasWidth = ins.getDataset().width  
                const canvasHeight = ins.getDataset().height  
                const canvasEle = document.querySelectorAll('.canvas>canvas')[0]  
                const ctx = canvasEle.getContext('2d')  

                const ballList = []  
                const speed = 3  
                const layer = 3  
                const ballInlayer = 20  

                for (let i = 0; i < layer; i++) {  
                    const radius = getDistance(canvasWidth / 2, canvasHeight / 2) / layer * i  
                    for (let j = 0; j < ballInlayer; j++) {  
                        const deg = j * 2 * Math.PI / ballInlayer  
                        const x = radius * Math.cos(deg) + canvasWidth / 2  
                        const y = radius * Math.sin(deg) + canvasHeight / 2  
                        const vx = speed * Math.cos(deg)  
                        const vy = speed * Math.sin(deg)  
                        ballList.push(new Ball({  
                            x,  
                            y,  
                            vx,  
                            vy,  
                            canvasWidth,  
                            canvasHeight,  
                            ctx  
                        }))  
                    }  
                }  

                const image = new Image()  
                const imageSrc = ins.getDataset().image || 'static/test/blurred_transparent_image.png'  
                image.src = imageSrc  

                image.onload = () => {  
                    const drawAll = () => {  
                        ctx.clearRect(0, 0, canvasWidth, canvasHeight)  
                        ballList.forEach(ball => {  
                            ball.move()  
                            ball.draw()  
                        })  
                        ctx.drawImage(image, this.imgState.x, this.imgState.y, this.imgState.width, this.imgState  
                            .height)  
                        requestAnimationFrame(drawAll)  
                    }  
                    drawAll()  
                }  
            },  

            onMessage(newVal, owner, ins) {  
                const data = newVal  
                const canvasEle = document.querySelectorAll('.canvas>canvas')[0]  
                const rect = canvasEle.getBoundingClientRect()  

                if (data.type === 'touchstart') {  
                    const x = data.x - rect.left  
                    const y = data.y - rect.top  
                    const img = this.imgState  
                    if (x >= img.x && x <= img.x + img.width && y >= img.y && y <= img.y + img.height) {  
                        this.dragging = true  
                        img.offsetX = x - img.x  
                        img.offsetY = y - img.y  
                    }  
                }  

                if (data.type === 'touchmove' && this.dragging) {  
                    const x = data.x - rect.left  
                    const y = data.y - rect.top  
                    this.imgState.x = x - this.imgState.offsetX  
                    this.imgState.y = y - this.imgState.offsetY  
                }  

                if (data.type === 'touchend') {  
                    this.dragging = false  
                }  
            }  
        }  
    }  
</script>  

<script>  
    export default {  
        data() {  
            return {  
                canvasWidth: 0,  
                startStatus: false,  
                touchOperation: {  
                    type: '',  
                    x: 0,  
                    y: 0  
                },  
                imageSrc: 'static/test/blurred_transparent_image.png'  
            }  
        },  
        onReady() {  
            this.$nextTick(() => {  
                uni.createSelectorQuery()  
                    .select(".canvas")  
                    .boundingClientRect(data => {  
                        this.canvasWidth = data.width  
                        this.startStatus = true  
                    })  
                    .exec()  
            })  
        },  
        methods: {  
            onTouchStart(e) {  
                const touch = e.touches[0]  
                this.touchOperation = {  
                    type: 'touchstart',  
                    x: touch.x,  
                    y: touch.y  
                }  
            },  
            onTouchMove(e) {  
                const touch = e.touches[0]  
                this.touchOperation = {  
                    type: 'touchmove',  
                    x: touch.x,  
                    y: touch.y  
                }  
            },  
            onTouchEnd() {  
                this.touchOperation = {  
                    type: 'touchend'  
                }  
            },  
            // 新增:选择图片方法  
            chooseImage() {  
                uni.chooseImage({  
                    count: 1,  
                    sizeType: ["original"],  
                    success: (res) => {  
                        // 获取临时文件路径  
                        const tempFilePath = res.tempFilePaths[0]  
                        this.imageSrc = tempFilePath;  

                        console.log("图片路径: ", this.imageSrc);  

                        // 通知 renderjs 模块更新图片路径  
                        this.$nextTick(() => {  
                            this.startStatus = false // 重置动画  
                            setTimeout(() => {  
                                this.startStatus = true // 重新触发 start  
                            }, 50)  
                        })  
                    }  
                })  
            }  
        }  
    }  
</script>  

<style>  
    .page-body-wrapper {  
        text-align: center;  
    }  

    .canvas {  
        width: 610rpx;  
        height: 610rpx;  
        margin: auto;  
        background-color: #fff;  
    }  
</style>

操作步骤:
  • 将图片附件保存到工程 static/test 目录下和手机相册
  • 运行工程
  • 点击 "选择图片" 按钮, 选择图片附件

预期结果:

通过 chooseImage API 获取的图片有透明度

实际结果:

通过 chooseImage API 获取的图片没有透明度

bug描述:

调用 chooseImage API 选择半透明图, chooseImage API 响应的图片没有透明度.

页面一开始就绘制 'static/test/blurred_transparent_image.png'(附件), 此时可以发现图片有透明度, 但是通过 chooseImage API 获取的附件没有透明度, 原因是图片的位深变成了24位.

2025-06-16 18:45 负责人:DCloud_iOS_WZT 分享
已邀请:

要回复问题请先登录注册