Search code examples
reactjsreact-image-crop

Get cropped image via react-image-crop module


could you help me how can I get output (source of cropped image) via react-image-crop module? Upload component looks like this:

class MyUpload extends Component {
constructor() {
    super();
    this.state = {
        src: 'source-to-image',
        crop: {
            x: 10,
            y: 10,
            aspect: 9 / 16,
            width: 100
        }
    }
}

onCropComplete = (crop, pixelCrop) => {
    this.setState({
        crop
    })
};

render() {
    return (
           <ReactCrop
                    src={this.state.src}
                    onComplete={this.onCropComplete}
                />
    );
} }

Method onCropComplete returns only coordinates, width and height of cropped image, not source. I would like to get blob file.


EDIT (working solution -- thanks for Mosè Raguzzini reply):

If someone has similiar problem, call getCropptedImg function from tutorial in your component and create url from returned Blob object, like this:

getCroppedImg(this.state.image, pixelCrop, 'preview.jpg')
            .then((res) => {
                const blobUrl = URL.createObjectURL(res);
                console.log(blobUrl); // it returns cropped image in this shape of url: "blob:http://something..."
            })

Solution

  • react-image-crop is not meant to be used to produce blobs, is only meant to crop images inline. Probably you need something like https://foliotek.github.io/Croppie/

    UPDATE: Check the section "What about showing the crop on the client?" at bottom of https://www.npmjs.com/package/react-image-crop, the blob is available as hidden feature

    /**
     * @param {File} image - Image File Object
     * @param {Object} pixelCrop - pixelCrop Object provided by react-image-crop
     * @param {String} fileName - Name of the returned file in Promise
     */
    function 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 Base64 string
      // const base64Image = canvas.toDataURL('image/jpeg');
     
      // As a blob
      return new Promise((resolve, reject) => {
        canvas.toBlob(file => {
          file.name = fileName;
          resolve(file);
        }, 'image/jpeg');
      });
    }
     
    async test() {
      const croppedImg = await getCroppedImg(image, pixelCrop, returnedFileName);
    }