uni-app drawImage绘制getImageInfo获取的path不展示

uni-app drawImage绘制getImageInfo获取的path不展示

开发环境 版本号 项目创建方式
Windows Window 10 HBuilderX
产品分类:uniapp/小程序/微信

PC开发环境操作系统:Windows

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

HBuilderX类型:正式

HBuilderX版本号:4.76

第三方开发者工具版本号:1.06.2504030

基础库版本号:3.9.2

项目创建方式:HBuilderX

示例代码:
```javascript
canvasSize: uni.upx2px(313) + 55, // 增加边距  
canvasScale: 3,  
dotArry:[{img:`![image](${'http://xxxxxxx.png'})`}]  
async drawBracelet() {  
    try {  
        this.ctx = uni.createCanvasContext('braceletCanvas', this);  

        // 设置Canvas尺寸  
        const canvasSize = this.canvasSize;  
        const center = canvasSize / 2;  
        const diameter = uni.upx2px(parseFloat(this.contentSize));  
        const radius = diameter / 2;  

        // 清空画布  
        this.ctx.clearRect(0, 0, canvasSize, canvasSize);  

        // 绘制背景圆形  
        this.ctx.beginPath();  
        this.ctx.arc(center, center, radius, 0, Math.PI * 2);  
        this.ctx.fillStyle = 'transparent';  
        this.ctx.fill();  
        this.ctx.strokeStyle = '#dcdcdc';  
        this.ctx.lineWidth = 1;  
        this.ctx.stroke();  

        console.log('绘制背景圆形');  
        // 加载所有图片信息  
        const imageTasks = this.dotArry.map((item) => {  
            return new Promise((resolveImg) => {  
                uni.getImageInfo({  
                    src: item.img,  
                    success: (res) => {  
                        console.log('下载图片成功', res);  
                        resolveImg({ path: res.path, item });  
                    },  
                    fail: () => {  
                        console.error('加载图片失败:', item.img);  
                        resolveImg(null); // 即使失败也resolve,避免Promise.all中断  
                    }  
                });  
            });  
        });  
        const images = await Promise.all(imageTasks);  
        console.log('加载所有图片信息', images);  

        // 绘制每个珠子 - 修改后的逻辑  
        for (let i = 0; i < images.length; i++) {  
            const { path, item } = images[i];  
            const width = uni.upx2px(parseFloat(this.dotwidth1(item)));  
            const height = uni.upx2px(parseFloat(this.dotheight(item)));  
            const rotation = (item.rotate * Math.PI) / 180; // 转换为弧度  

            this.ctx.save();  

            // 移动到画布中心  
            this.ctx.translate(center, center);  

            // 应用旋转  
            this.ctx.rotate(rotation);  

            // 应用垂直平移(对应DOM中的translateY(calc(-${contentSize}/2)))  
            this.ctx.translate(0, -radius);  

            // 应用水平翻转(如果scaleX为-1)  
            if (item.scaleX === -1) {  
                this.ctx.scale(-1, 1);  
            }  

            // 应用垂直翻转(对应DOM中的scaleY(-1))  
            this.ctx.scale(1, -1);  

            console.log('绘制珠子', path);  
            // 绘制图片(调整位置使图片中心对齐)  
            this.ctx.drawImage(path, -width / 2, -height / 2, width, height);  

            this.ctx.restore();  
        }  
        // 等待绘制完成  
        await new Promise((resolve) => {  
            this.ctx.draw(false, () => {  
                setTimeout(resolve, 3000); // 增加一点延迟确保绘制完成  
            });  
        });  
        console.log('等待Canvas绘制完成');  
        // 导出图片  
        const { tempFilePath } = await new Promise((resolve, reject) => {  
            uni.canvasToTempFilePath({  
                canvasId: 'braceletCanvas',  
                fileType: 'png',  
                quality: 1,  
                width: canvasSize,  
                height: canvasSize,  
                destWidth: canvasSize * this.canvasScale,  
                destHeight: canvasSize * this.canvasScale,  
                success: resolve,  
                fail: reject  
            });  
        });  
        console.log('导出图片', tempFilePath);  
        // 上传图片  
        const { url } = await upFile(tempFilePath);  

        return url;  
    } catch (error) {  
        console.error('绘制手链失败:', error);  
        throw new Error('生成图片失败: ' + error.message);  
    }  
},
操作步骤:
-
预期结果:
ios 和 安卓 均可正常绘制

实际结果:
安卓绘制的没有图片

bug描述:
循环使用getImageInfo获取网络图片的临时路径使用drawImage绘制,
在iOS设备上正常,在安卓设备上绘制的图片不展示,只显示绘制的圆圈

更多关于uni-app drawImage绘制getImageInfo获取的path不展示的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

测试一下原生微信小程序是否也有这个问题

更多关于uni-app drawImage绘制getImageInfo获取的path不展示的实战教程也可以访问 https://www.itying.com/category-93-b0.html


这是一个常见的平台兼容性问题。在 Android 平台上,getImageInfo 获取的临时路径在 drawImage 使用时存在限制。

主要问题及解决方案:

  1. 路径格式问题

    • Android 对临时路径的处理与 iOS 不同,建议在 drawImage 前对路径进行验证:
    if (path && path.startsWith('http')) {
      // 如果是网络路径,需要重新下载或使用其他方式处理
      console.error('Invalid path for drawImage:', path);
      continue;
    }
    
  2. 图片加载时机

    • Android 可能需要更多时间处理图片缓存,建议在绘制前增加延迟:
    await new Promise(resolve => setTimeout(resolve, 50));
    this.ctx.drawImage(path, -width / 2, -height / 2, width, height);
    
  3. 替代方案 考虑使用 uni.downloadFile 替代 getImageInfo

    uni.downloadFile({
      url: item.img,
      success: (res) => {
        if (res.statusCode === 200) {
          resolveImg({ path: res.tempFilePath, item });
        }
      }
    });
    
  4. 绘制顺序优化 确保所有图片都完全加载后再开始绘制,可以在 Promise.all 后添加检查:

    const validImages = images.filter(img => img && img.path);
    if (validImages.length === 0) return;
回到顶部