react-image-crop icon indicating copy to clipboard operation
react-image-crop copied to clipboard

Cropping images from react-webcam

Open miag676 opened this issue 4 years ago • 2 comments

Hello,

firstly, thanks for making this great library. I am trying to use it to crop images taken by react-webcam (npm library). The images taken by the library don't seem get stored to local, so I'm thinking this is the reason I'm running into a problem. In this component <ReactCrop src={imgSrc} crop={crop} onChange={newCrop => setCrop(newCrop)} /> I insert the imgSrc, which is the image taken by the webcam. It is displayed on the site in the ReactCrop component, however, once I try to crop the photo the canvas doesn't show anything. Just the dimension of canvas changes, when I change the dimension of the crop. Could this be happening because the photo is taken with webcam and not stored?

Any help would be appreciated!

Here is my full code:

import React, { Component, useEffect, useRef, useState, useCallback } from "react";
import 'react-image-crop/dist/ReactCrop.css';
import ReactCrop from 'react-image-crop';

const videoConstraints = {
    width: 1280,
    height: 720,
    facingMode: "user"
  };

const Camera = () => {
  const webcamRef = React.useRef(null);
  const [imgSrc, setImgSrc] = React.useState(null);
  const [crop, setCrop] = React.useState()
  const [completedCrop, setCompletedCrop] = React.useState(null);
  const previewCanvasRef = useRef(null)
  
  const stop =  React.useCallback(() => {
    let stream = webcamRef.current.video.srcObject;
    const tracks = stream.getTracks();
    tracks.forEach(track => track.stop());
    webcamRef.current.video.srcObject = null;
  },[webcamRef, setImgSrc]);
 
  const capture = React.useCallback(() => {
    const imageSrc = webcamRef.current.getScreenshot();
    setImgSrc(imageSrc);
    stop()
  }, [webcamRef, setImgSrc]);

  useEffect(() => {
    if (!completedCrop || !previewCanvasRef.current || !imgSrc.current) {
      return;
    }
    const image = imgSrc.current;
    const canvas = previewCanvasRef.current;
    const crop = completedCrop;

    const scaleX = image.naturalWidth / image.width;
    const scaleY = image.naturalHeight / image.height;
    const ctx = canvas.getContext('2d');
    const pixelRatio = window.devicePixelRatio;

    canvas.width = crop.width * pixelRatio * scaleX;
    canvas.height = crop.height * pixelRatio * scaleY;

    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 * scaleX,
      crop.height * scaleY
    );
  }, [completedCrop]);

  return (
    <>
      <Webcam
        audio={false}
        ref={webcamRef}
        screenshotFormat="image/jpeg"
      />
      <button onClick={capture}>Capture photo</button>
      {imgSrc && (
        <>
        <ReactCrop src={imgSrc} crop={crop} onChange={newCrop => setCrop(newCrop)} onComplete={(c) => setCompletedCrop(c)}></ReactCrop>
        <canvas 
                  ref={previewCanvasRef}
                  style={{
                    width: Math.round(completedCrop?.width ?? 0),
                    height: Math.round(completedCrop?.height ?? 0)
                  }}
        />
        </>
      )}    
    </>
  ) 
}
export default Camera```

miag676 avatar Sep 14 '21 18:09 miag676

it the problem already solved?

PixelsLan avatar Jul 28 '22 07:07 PixelsLan

No, unfortunately not.

miag676 avatar Jul 28 '22 08:07 miag676