腰酸背痛的小田 2024-10-13 11:29 采纳率: 0%
浏览 5
问题最晚将于10月21日00:00点结题

微信小程序 canvas 问题

微信小程序,调用手机相册,或者相机拍摄,然后拿到临时图片。再用canvas给图片添加一个当前时间的水印。最后本地预览,同时上传服务器。
但是在开发者工具里面,和安卓手机上,都完全没问题。但是在苹果手机上,就不行了。请帮忙看什么问题。谢。有酬劳

打印data.path的结果是:(两次打印,临时路径的 前缀 不一样)
安卓版本:"http://tmp/tOln3OeToOQOb7131f7b99e0f4924532d03b3bf68b15.png"。
ios版本 的是:path: "wxfile://tmp_99348563a6d7ae65d2c1bf5baf94af1e.jpg"

ios版本真机调试打印结果

img

安卓和开发工具调试打印的结果

img

const data = this.data.photoData
        console.log('组件里面的 图片data', data);
        const width = data.width
        const height = data.height
        const time = util.nowdate('time');
        this.setData({
            canvasWidthValue: width,
            canvasHeightValue: height,
        })

        this.createSelectorQuery()
            .select('#myCanvas') // 在 WXML 中填入的 id
            .fields({ node: true, size: true })
            .exec((res) => {
                const canvas = res[0].node
                const ctx = canvas.getContext('2d')

                canvas.width = width
                canvas.height = height
                console.log('Canvas 对象 res', res);
            
                wx.getImageInfo({
                    src: data.path,  // 图片的路径
                    success: (res) => {
                        console.log('图片加载完成res',res);
                        const image = canvas.createImage();
                        console.log('创建image',image);

                        image.src = res.path; // 使用本地路径加载
                        image.onload = () => {
                            ctx.drawImage(image, 0, 0, width, height)
                            ctx.font = '30px Arial'; // 这里设置字体大小为30px,字体为Arial
                            const textWidth = ctx.measureText(time).width + 40;
                            const canvasWidth = canvas.width;
                            const canvasHeight = canvas.height;
                            ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'; // 设置背景颜色为半透明的黑色
                            const x = canvasWidth - textWidth;
                            const y = canvasHeight - 60;
                            ctx.fillRect(x, y, textWidth, 80);
                            ctx.fillStyle = 'rgba(255, 255, 255, 0.7)'; // 设置字体颜色为白色
                            // 计算文本的起始坐标,使其位于背景的中心
                            const textX = x + (textWidth - ctx.measureText(time).width) / 2;
                            const textY = y + 40; // 假设行高为字体大小
                            ctx.fillText(time, textX, textY);        // 绘制文本
                            wx.canvasToTempFilePath({
                                canvas,
                                x: 0,
                                y: 0,
                                width: canvasWidth,
                                height: canvasHeight,
                                success: res => {
                                    // 生成的图片临时文件路径
                                    const tempFilePath = res.tempFilePath
                                    console.log('生成的图片临时文件路径 tempFilePath:', tempFilePath);
                                    this.setData({
                                        watermarkedImage: tempFilePath
                                    })
                                },
                                fail: err => {
                                    console.log('err', err);
                                }
                            })
                        }
                        image.onerror = (err) => {
                            console.error('图片加载失败', err);
                        };
                    
                    },
                    fail: (err) => {
                        console.error('获取图片信息失败', err);
                    }
                });
            })
  • 写回答

8条回答 默认 最新

  • 杨同学* 2024-10-13 14:17
    关注

    该回答引用ChatGPT4o及杨同学*共同作答, 如有帮助,还请采纳。
    根据你的描述和代码分析,这个问题可能是由于iOS系统对Canvas API、图片处理或异步加载的特殊处理导致的。在安卓和开发者工具上运行正常,但在iOS真机上出现问题,说明可能存在以下问题

    可能的原因分析

    1. Canvas相关问题:

      • iOS对Canvas绘图和canvasToTempFilePath方法有更严格的权限限制或渲染顺序问题,导致部分操作在iOS上不生效。
    2. 图片加载与跨域问题:

      • iOS真机在加载图片时对路径和图片格式可能更敏感。如果你从相册/相机获取的图片路径不符合iOS的要求,image.src可能加载失败。
      • 如果wx.getImageInfo返回的图片路径不符合iOS的要求,可能导致image.onload不触发。
    3. 异步执行顺序问题:

      • iOS系统对图片加载和Canvas渲染的异步处理比较严格,Canvas在图片未完全加载时绘制可能会导致渲染失败。
    4. 图片路径兼容性问题:

      • wx.getImageInfo返回的路径在iOS和安卓可能不同,某些情况可能需要通过res.pathdata.path进行路径处理。

    解决方案与调整

    1. 确保图片路径的正确性:

      • wx.getImageInfo成功回调里,多打印一些信息,确认iOS真机返回的路径是正确的:

        console.log('iOS 图片路径:', res.path);
        console.log('原始路径:', data.path);
        
      • 尝试将image.src设置为data.path而非res.path,以确保路径一致。

        image.src = data.path;  // 尝试直接使用原始路径
        
    2. Canvas的异步绘制顺序优化:

      • iOS可能会对Canvas操作有延迟,所以可以尝试在image.onload中添加短暂的延时(比如50ms),以确保Canvas在图片完全加载后绘制。

        image.onload = () => {
            setTimeout(() => {
                ctx.drawImage(image, 0, 0, width, height);
                // 其他绘制操作...
            }, 50);
        };
        
    3. 确保Canvas环境的初始化正确:

      • 确保createSelectorQuery()获取的canvasctx对象在iOS上是正常的,并且正确地初始化了尺寸。

        console.log('Canvas对象:', canvas, ctx);
        
    4. 检查canvasToTempFilePath使用的参数:

      • iOS真机上对canvasToTempFilePath的使用有时比较严格,建议补充以下参数:

        wx.canvasToTempFilePath({
            canvas,
            x: 0,
            y: 0,
            width: canvasWidth,
            height: canvasHeight,
            destWidth: canvasWidth * 2,  // 输出的分辨率提高(避免图片模糊)
            destHeight: canvasHeight * 2,
            success: res => {
                const tempFilePath = res.tempFilePath;
                console.log('生成的图片临时文件路径:', tempFilePath);
                this.setData({ watermarkedImage: tempFilePath });
            },
            fail: err => {
                console.log('canvasToTempFilePath 错误:', err);
            }
        });
        
    5. 检查image.onerror是否触发:

      • 如果图片加载失败,image.onerror会触发。确保在iOS真机调试时观察这个错误信息:

        image.onerror = (err) => {
            console.error('iOS 图片加载失败', err);
        };
        
    6. 使用高清模式渲染(Retina支持):

      • iOS设备的Retina屏幕对Canvas的绘制有特殊要求,尝试设置高清模式:

        const dpr = wx.getSystemInfoSync().pixelRatio;
        canvas.width = width * dpr;
        canvas.height = height * dpr;
        ctx.scale(dpr, dpr);
        

    总结

    根据你的问题描述,iOS真机上的问题通常是图片加载路径不一致、异步加载顺序、Canvas初始化、Retina屏幕适配等方面的问题。
    建议你逐步检查以下几点:

    1. 确认wx.getImageInfo返回的图片路径是否正确。
    2. image.onload内添加短暂延时,确保图片完全加载。
    3. 检查canvasToTempFilePath的参数,确保在iOS上符合要求。
    4. 使用pixelRatio确保Canvas在高清屏幕上正确渲染。

    通过以上调整应该能解决iOS真机上的Canvas渲染问题。如果仍然有问题,可以贴出iOS上的详细错误日志,我可以进一步帮你排查。

    评论

报告相同问题?

问题事件

  • 修改了问题 今天
  • 创建了问题 今天

悬赏问题

  • ¥15 如何让子窗口鼠标滚动独立,不要传递消息给主窗口
  • ¥15 如何能达到用ping0.cc检测成这样?如图
  • ¥15 关于#DMA固件#的问题,请各位专家解答!
  • ¥15 matlab生成的x1图不趋于稳定,之后的图像是稳定的水平线
  • ¥15 请问华为OD岗位的内部职业发展通道都有哪些,以及各个级别晋升的要求
  • ¥20 微信小程序 canvas 问题
  • ¥15 系统 24h2 专业工作站版,浏览文件夹的图库,视频,图片之类的怎样删除?
  • ¥15 怎么把512还原为520格式
  • ¥15 MATLAB的动态模态分解出现错误,以CFX非定常模拟结果为快照
  • ¥15 求高通平台Softsim调试经验