Получите обрезанное изображение с помощью модуля реагирования-обрезки изображения - PullRequest
1 голос
/ 09 апреля 2019

Я пытаюсь получить обрезанное изображение с помощью модуляact-image-crop (blob).Однако у меня есть проблема с canvas, я думаю, что это нужно делать асинхронно, но я не уверен и не уверен, что я выбрал правильный подход.

Я пыталсясделать то же самое, что написано в документации о response-image-crop в https://www.npmjs.com/package/react-image-crop. Я также пытаюсь сделать то же самое, что и Stefan в этой теме: Получить обрезанное изображение через модуль response-image-crop

state = {
        image: '',
        crop: {
            aspect: 4/3,
            x: 10,
            y: 10,
            width: 80,
            height: 80,
           },
        imgSrc: null
    }

    getCroppedImg = (image, pixelCrop, fileName) => {

        const canvas = document.createElement('canvas');
        canvas.width = pixelCrop.width;
        canvas.height = pixelCrop.height;
        const ctx = canvas.getContext('2d');

        ctx.drawImage(
          image,
          pixelCrop.x,
          pixelCrop.y,
          pixelCrop.width,
          pixelCrop.height,
          0,
          0,
          pixelCrop.width,
          pixelCrop.height
        );

        // As a blob
        return new Promise((resolve, reject) => {
          canvas.toBlob(blob => {
            blob.name = fileName;
            resolve(blob);
          }, 'image/jpeg');
        });
      }

    handleImageUpload = e => {
        const uploadData = new FormData();
        uploadData.append("image", this.state.imgSrc);

        service.handleUpload(uploadData)
            .then(response => {
            this.setState({ image: response.secure_url });
            })
            .catch(err => {
            console.log("Error while uploading the file: ", err);
            });
    }

    handleImagePreview = e => {
        this.setState({image: URL.createObjectURL(e.target.files[0]), imgSrc: e.target.files[0]})
    }

    handleOnCropComplete = (crop, pixelCrop) => {
        this.getCroppedImg(this.state.imgSrc, pixelCrop, 'preview.jpg')
        .then((res) => {
            const blobUrl = URL.createObjectURL(res);
            console.log(blobUrl);
        })

    }
render() {
        return(
            <>
                <input required onChange={this.handleImagePreview} type="file" />                 
                <div className="crop-div">
                                <ReactCrop 
                                    src={this.state.image} 
                                    crop={this.state.crop} 
                                    onChange={this.handleOnCropChange}
                                    onComplete={this.handleOnCropComplete} />
                                <button className="submit-btn" onClick={this.handleImageUpload}>Crop the image</button>
                            </div>
            </>
        )
    }

После изменения размера обрезанной области на изображении я получу эту ошибку:

"Ошибка типа: не удалось выполнить 'drawImage' для 'CanvasRenderingContext2D': указанное значение не являетсятипа '(CSSImageValue или HTMLImageElement или SVGImageElement или HTMLVideoElement или HTMLCanvasElement или ImageBitmap или OffscreenCanvas)' "

Изображение, которое я передаю, является объектом файла изображения.

1 Ответ

0 голосов
/ 25 апреля 2019

Файлового объекта нет в списке, ожидаемом, как указано в сообщении об ошибке, поэтому вы должны создать объект в списке из имеющегося у вас объекта.
В этом случае мы будем использовать HTMLImageElement.

getCroppedImg = (imageFile, pixelCrop, fileName) => {

    const canvas = document.createElement('canvas');
    canvas.width = pixelCrop.width;
    canvas.height = pixelCrop.height;
    const ctx = canvas.getContext('2d');

    var image = new Image();
    var promise = new Promise((resolve, reject) => {
      image.onload = function(){ 

        ctx.drawImage(
          image,
          pixelCrop.x,
          pixelCrop.y,
          pixelCrop.width,
          pixelCrop.height,
          0,
          0,
          pixelCrop.width,
          pixelCrop.height
        );
        resolve();
      };
      image.src = URL.createObjectURL(imageFile);
    }).then(function(){
      return new Promise(resolve, reject) => {
        canvas.toBlob(blob => {
          blob.name = fileName;
          resolve(blob);
        }, 'image/jpeg');
      });  
    });
    return promise;
  }
...