LoginSignup
5
2

More than 3 years have passed since last update.

react-image-cropで画像のトリミング機能を実装する方法

Posted at

react-image-cropを用いたトリミング機能を追加するところで躓いたので、自分へのメモとして書きました。

state

index.tsx
const [src, setSrc] = useState<any>(null);
const [crop, setCrop] = useState<Crop>({
    unit: "%",
    x: 0,
    y: 0,
    width: 50,
    height: 50,
    aspect: 1
});
const [imageRef, setImageRef] = useState<HTMLImageElement | null>(null);

画像を読み込む関数

index.tsx
const onSelectFile = (event: React.ChangeEvent<HTMLInputElement>) => {
    if (event.target.files !== null) {
        const reader = new FileReader();
        reader.addEventListener("load", () =>
            setSrc(reader.result);
        );
        reader.readAsDataURL(event.target.files[0]);
    }
};

const onImageLoaded = (image: HTMLImageElement) => 
    setImageRef(image);
};

画像をトリミングする関数

index.tsx
const onCropChange = (crop: Crop) => {
    setCrop(crop);
};

const onCropComplete = (crop: any) => {
    if(imageRef && crop.width && crop.height){
        const canvas = document.createElement("canvas")
        const scaleX = imageRef.naturalWidth / imageRef.width;
        const scaleY = imageRef.naturalHeight / imageRef.height;
        canvas.width = crop.width
        canvas.height = crop.height
        const ctx = canvas.getContext("2d")
        if (ctx !== null) {
            ctx.drawImage(
                imageRef,
                crop.x * scaleX,
                crop.y * scaleY,
                crop.width * scaleX,
                crop.height * scaleY,
                0,
                0,
                crop.width,
                crop.height
            )
        }
    }
};

コンポーネント

index.tsx
import React, {useState} from "react";
import ReactCrop, {Crop} from "react-image-crop";
import "react-image-crop/dist/ReactCrop.css";

export const CropModal: React.FC<Props> = props => {
    ...
    return (
        <div>
            <input type="file" accept="image/*" onChange={onSelectFile} />
            {src && (
                <ReactCrop
                    src={src}
                    crop={crop}
                    ruleOfThirds
                    onImageLoaded={onImageLoaded}
                    onComplete={onCropComplete}
                    onChange={onCropChange}
                />
            )}

        <div/>
    )
}

今回トリミングした画像データをサーバーにアップロードするには、canvasのデータをBlobデータに変換し、axiosを用いてDataFormとして送る。

canvasの画像データをblobに変換し、axiosでpost.する方法

参考にした記事

react-image-crop - npm
react-image-crop dom CodeSandBox

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2