You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中使用canvas drawImage加载本地图片报错问题

解决Next.js中Canvas加载本地图片报错的问题

问题原因

  • 混淆组件与原生构造函数:你导入的Image from "next/image"是Next.js的图片优化组件,并非浏览器原生的HTMLImageElement构造函数。用它创建的实例是React组件,不符合drawImage要求的参数类型,直接导致报错。
  • 服务端环境限制:Image是浏览器全局对象,在服务端(比如getStaticProps中)不存在,直接调用会提示方法未定义。

解决方案

1. 改用浏览器原生Image构造函数

删除或重命名Next.js的Image导入,避免命名冲突。将创建Image实例的逻辑放在useEffect中执行——useEffect的回调仅在客户端运行,能规避服务端环境缺失浏览器API的问题。

2. 正确处理Next.js本地图片路径

public目录下的图片直接使用根路径(如/map.png)即可,Next.js会自动解析资源位置;也可以通过require("../public/map.png").default获取图片URL。

修正后的代码

import React, { useRef, useEffect } from "react";

const Canvas = (props) => {
    const canvasRef = useRef(null);

    useEffect(() => {
        const canvas = canvasRef.current;
        const context = canvas.getContext('2d');

        // 初始化画布背景
        context.fillStyle = "#000000";
        context.fillRect(0, 0, canvas.width, canvas.height);

        // 创建原生HTMLImageElement实例
        const image = new Image();
        // 指向public目录下的图片,直接用根路径
        image.src = "/map.png";

        // 图片加载完成后绘制到画布
        const handleLoad = () => {
            context.drawImage(image, 0, 0);
        };
        image.addEventListener('load', handleLoad);

        // 清理事件监听,防止内存泄漏
        return () => {
            image.removeEventListener('load', handleLoad);
        };
    }, []);

    return <canvas ref={canvasRef} {...props} width={288} height={480} />;
};

export default Canvas;

关键说明

  • 画布绘图必须使用浏览器原生的new Image()创建图片实例,不能用Next.js的Image组件替代。
  • 所有依赖浏览器API的操作(如创建Image、操作Canvas)都要放在useEffect中,确保仅在客户端执行。
  • public目录是Next.js的静态资源目录,资源路径直接以/开头即可访问,无需写相对路径。

内容的提问来源于stack exchange,提问作者risky last

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 21:06:24