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

react-image-crop中drawImage执行失败:参数类型错误求解决方案

修复react-image-crop裁剪时drawImage类型错误

问题原因

你的代码中image状态始终为null,没有正确关联到<ReactCrop>内部的<img> DOM元素,导致调用ctx.drawImage()时传入的第一个参数不是合法的图片元素类型,触发类型错误。

修复步骤

  • 为<img>元素添加React ref,用于获取真实的DOM节点
  • 在图片的onLoad事件中,将DOM节点存入image状态,确保图片加载完成后再进行裁剪操作
  • 给crop状态设置初始值,避免裁剪参数为undefined
  • 在cropImageNow函数中增加空值校验,防止未加载完成或未设置裁剪区域时执行报错

修复后完整代码

import React, { useState, useRef } from 'react'
import ReactCrop from 'react-image-crop'
import 'react-image-crop/dist/ReactCrop.css'

export const Imagecrop = () => {
    const [src, setSrc] = useState(null)
    const [image, setImage] = useState(null)
    const [crop, setCrop] = useState({ aspect: 800 / 200 })
    const [result, setResult] = useState(null);
    const imgRef = useRef(null)

    const handleFileChange = e => {
        if (e.target.files[0]) {
            setSrc(URL.createObjectURL(e.target.files[0]))
        }
    }

    const handleImageLoad = () => {
        setImage(imgRef.current)
    }

    const cropImageNow = () => {
        if (!image || !crop || !crop.width || !crop.height) return;

        const canvas = document.createElement('canvas');
        const scaleX = image.naturalWidth / image.width;
        const scaleY = image.naturalHeight / image.height;
        const pixelRatio = window.devicePixelRatio;

        canvas.width = crop.width * pixelRatio;
        canvas.height = crop.height * pixelRatio;
        const ctx = canvas.getContext('2d');
        
        ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
        ctx.imageSmoothingQuality = 'high';

        ctx.drawImage(
            image,
            crop.x * scaleX,
            crop.y * scaleY,
            crop.width * scaleX,
            crop.height * scaleY,
            0,
            0,
            crop.width,
            crop.height,
        );

        const base64Image = canvas.toDataURL('image/jpeg');
        setResult(base64Image);
    };

    return (
        <div className='container'>
            <div className='row'>
                <div className='col-6'>
                    <input type='file' accept='image/*' onChange={handleFileChange} />
                </div>
                <div className='col-6'>
                    {src && (
                        <ReactCrop crop={crop} aspect={800 / 200} onChange={setCrop}>
                            <img 
                                src={src} 
                                ref={imgRef} 
                                onLoad={handleImageLoad} 
                            />
                        </ReactCrop>
                    )}
                    {src && <button onClick={cropImageNow}>Crop</button>}
                </div>
            </div>
            {/* 可选:展示裁剪结果 */}
            {result && (
                <div className='mt-3'>
                    <h4>裁剪结果</h4>
                    <img src={result} alt="裁剪后的图片" style={{ maxWidth: '100%' }} />
                </div>
            )}
        </div>
    )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 22:25:18