最好用的React图像裁剪库

7,053 阅读8分钟

在建立一个应用程序时,最佳实践要求减少图像周围的噪音,从而将用户的注意力吸引到图像的特定部分。图像裁剪是一种处理图像的方法,以去除任何不需要的元素。通过改变长宽比或方向,我们可以把观众的目光吸引到照片的主体上,并改善整体构图。

在这篇文章中,我们将比较三个顶级的React图像裁剪库,React Avatar Editor、react-cropper和react-easy-crop,从性能、受欢迎程度和开发者经验方面对每个库进行评估。

首先,我们将在React中建立一个图片上传器应用程序,我们将在每个库中使用它。在本教程结束时,你应该能够为你的项目选择合适的对象。要跟上本教程,你将需要。

  • React和JavaScript的基本知识
  • 在你的机器上安装Node.js和npm

让我们开始吧!

你可以通过访问项目的代码来进行学习。

用Create React App初始化一个新的React应用

我们先用Create React App初始化一个新的React应用并引导它;在你的终端运行下面的命令来创建一个新的React应用。

npx create-react-app image uploader

接下来,我们将导航到我们的项目目录,运行以下命令来启动我们的开发服务器。

cd image uploader && yarn start 

上面的命令将在我们的浏览器中打开一个标签,显示应用程序的默认模板。接下来,我们将安装依赖项,我们将把它们包括在我们的三个cropper库中。

依赖关系

我们将在我们的应用程序中安装以下依赖项。

接下来,我们将为我们的组件建立组件。在我们的应用程序中,我们将需要一个button 组件来上传图片,以及一个modals 组件,它将从我们的上传器中上传、保存和删除图片。最后,对于我们的每个裁剪器,我们将需要一个modalWrapper

Button 组件

Button 组件是我们应用程序中所有按钮的一个骨架组件。

首先,我们将使用样式组件来为我们的按钮创建一个样式指南。首先,让我们在我们应用程序的src 目录中创建一个components 文件夹。在你的components 文件夹中,创建一个新的目录,称为Button ;在这个文件夹中,创建一个Button. jsx 文件,并添加以下代码。

import styled from "styled-components";
const Button = ({ children, className, ...props }) => {
    return (
        <StyledButton
            style={{
                background: "skyblue",
                color: "#000",
            }}
            className={`${className} block text-black px-6 rounded-md font-semibold hover:opacity-75 transition-opacity duration-500 ease-in`}
            type="button"
            {...props}
        >
            {children}
        </StyledButton>
    );
};

在上面的代码块中,我们创建了一个Button 组件,并传递了childrenclassName ,和props 。现在,我们将用styled-components为我们的按钮添加样式

const StyledButton = styled.button`
    background-color: #2eff7b;
    border: none;
    outline: none;
    height: 45px;
    &:focus {
        border: none;
        outline: none;
    }
    &:disabled {
        opacity: 1;
        cursor: not-allowed;
    }
`;
export default Button;

Checkbox 组件

现在,我们将建立一个Checkbox 组件,链接每个图片裁剪器。首先,在我们的组件目录中创建一个名为Checkbox 的新文件夹。在里面,我们将创建一个名为Checkbox.jsx 的新文件并添加以下代码。

import styled from "styled-components";
const Checkbox = ({ label, onChange, id, isChecked }) => {
    return (
        <Wrapper>
            <label htmlFor={id}>{label}</label>
            <input
                id={id}
                type="checkbox"
                name={label}
                onChange={() => {
                    onChange(!isChecked ? label : null);
                }}
                value={isChecked ? label : ""}
                checked={isChecked}
            />
            <span className="rounded-full" />
        </Wrapper>
    );
};

在上面的代码块中,我们创建了一个Checkbox 组件,里面有一个标签和一个ID,
我们将用它来选择我们的裁剪器库。接下来,我们将建立一个modal 组件,用于打开和关闭一个特定的剪裁库。

创建我们的modal 组件

我们的模态组件将具有像onModalCloseshowModalonSaveHandler 这样的道具。我们还将添加一个按钮,用于上传和保存我们裁剪的图片。

在我们的components 目录中,让我们创建一个名为Modal 的新文件夹。在里面,创建一个名为Modal.jsx 的新文件,并添加下面的代码块。

import { createPortal } from "react-dom";
import styled from "styled-components";
import Button from "../Button/Button";
const Modal = ({ children, onModalClose, showModal, onSaveHandler }) => {
    return createPortal(
        <Wrapper
            style={{
                opacity: showModal ? 1 : 0,
                pointerEvents: showModal ? "all" : "none",
            }}
        >
            <div
                onClick={onModalClose}
                role="button"
                className="iu-modal-backdrop"
                style={{
                    display: showModal ? "flex" : "none",
                }}
            />
            <div className="iu-modal-content">
                {children}
                <footer className="px-12 md:sticky absolute bottom-0 bg-white w-full left-0 py-4 border-t border-black flex items-center justify-between">
                    <Button onClick={onModalClose}>Dismiss</Button>
                    <Button
                        onClick={() => {
                            onSaveHandler();
                            onModalClose();
                        }}
                    >
                        Save
                    </Button>
                </footer>
            </div>
        </Wrapper>,
        document.getElementById("modal")
    );
};

在上面的代码块中,我们初始化了一个modal 组件,并创建了一个Wrapper 组件,在这里我们添加了一个上传和保存图像的函数。

react-avatar-editor

react-avatar-editor是一个用于React应用程序的头像和图片裁剪器。通过一个直观的用户界面,react-avatar-editor可以轻松地裁剪、调整大小和旋转图片。

react-avatar-editor在npm上每周有8.5万次下载在GitHub上有1.8万颗星,是React应用中最受欢迎的裁剪器库之一。要看到 react-avatar-editor 的运行,首先,我们需要用下面的命令在我们的应用程序中安装它。

//Yarn 

yarn add react-avatar-editor

//npm

npm install --save react-avatar-editor

接下来,创建一个名为ReactAvatarEditor 的新文件夹。在里面,创建一个名为ReactAvatarEditor.jsx 的新文件,并添加以下代码。

import { useRef } from "react";
import AvatarEditor from "react-avatar-editor";
import styled from "styled-components";
import Modal from "../../Modal/Modal";

const ReactAvatarEditor = ({
    showModal,
    onModalClose,
    imgURL,
    onSaveHandler,
}) => {
    const EditorRef = useRef(null);
    const showCroppedImage = async () =&gt; {
        if (EditorRef.current) {
            const img = EditorRef.current.getImage().toDataURL();
            return img;
        }
    };

    return (
        <Modal
            showModal={showModal}
            onSaveHandler={async () => onSaveHandler(await showCroppedImage())}
            onModalClose={onModalClose}
        >
            <Wrapper className="w-full h-full flex flex-col items-center justify-center">
                <AvatarEditor
                    ref={EditorRef}
                    image={imgURL}
                    width={250}
                    height={250}
                    border={0}
                    scale={1.2}
                    color={[255, 255, 255, 0.6]}
                />
            </Wrapper>
        </Modal>
    );
};

在上面的代码中,我们导入了useRef Hook,将我们的cropper packager初始化为AvatarEditor ,并导入了styled-components来为我们的应用程序添加样式。

然后,我们用AvatarEditor 来初始化一个功能组件,并从我们的modal 组件中传递一些方法。最后,我们将ref 指派给我们的AvatarEditor ,以获得我们的图像,将其转换为URL,并对其进行解析以进行裁剪。

为了渲染我们裁剪过的图片,我们创建了一个包装组件并添加了道具,如image ,这是我们要裁剪的图片的URL。注意,width,height,border,color 指的是编辑器的属性。

react-cropper

react-cropperCropper.js的一个开源React包装组件,Cropper.js是一个包括照片编辑器和图片裁剪器的JavaScript库。 react-cropper在npm上有超过63k的每周下载量,在GitHub上有1.6k的星级。要在你的应用程序中使用 react-cropper,首先,用下面的命令安装它。

// Using yarn 
yarn add react-cropper 

// Using npm
npm install --save react-cropper 

接下来,添加下面的代码块,使用我们的图片上传器应用程序裁剪图片。

import { useRef, useState } from "react";
import Cropper from "react-cropper";
import "cropperjs/dist/cropper.css";
import Modal from "../../Modal/Modal";

const ReactCropper = ({ showModal, onModalClose, imgURL, onSaveHandler }) => {
    const cropperRef = useRef(null);
    const [croppedImg, setCroppedImg] = useState("");
    const onCrop = () => {
        const imageElement = cropperRef?.current;
        const cropper = imageElement?.cropper;
        setCroppedImg(cropper.getCroppedCanvas().toDataURL());
    };

    return (
        <Modal
            showModal={showModal}
            onSaveHandler={() => onSaveHandler(croppedImg)}
            onModalClose={onModalClose}
        >
            <Cropper
                src={imgURL}
                style={{ height: 500, width: "732px" }}
                initialAspectRatio={16 / 9}
                guides={false}
                crop={onCrop}
                ref={cropperRef}
                viewMode={1}
                // guides={true}
                minCropBoxHeight={10}
                minCropBoxWidth={10}
                // background={false}
                responsive={true}
                autoCropArea={1}
                aspectRatio={4 / 3}
                checkOrientation={false}
            />
        </Modal>
    );
};
export default ReactCropper;

与react-avatar-editor类似,我们从React导入了useRefuseState Hooks。接下来,我们初始化了一个功能组件,ReactCropper ,它接收了一些道具,如图片URL和modal

为了裁剪我们的图片,我们连接到图片裁剪器的属性,如图片URL,然后对其进行解析。使用React的useState Hook,我们为我们裁剪的图片创建了一个状态。

为了渲染我们的图像,我们初始化了一个Cropper 组件,并从Cropper.js 传递了一些道具,包括用于解析图像URL的src 。最后,我们向style 道具传递样式。

react-easy-crop

react-easy-crop是一个开源的React组件,它有一个简洁的UI来裁剪图片和视频。 react-easy-crop对移动设备很友好,提供了像素和百分比的裁剪尺寸,以及拖动和缩放的交互。

在npm上, react-easy-crop目前每周被下载超过12.5万次。在GitHub上,react-easy-crop有1.4万颗星。你可以通过使用软件包管理器安装该库来开始使用 react-easy-crop,如下面的代码块所示。

//Yarn 
yarn add react-easy-crop

// npm
npm install react-easy-crop --save

要使用 react-easy-crop,你需要把它包装在一个Cropper 组件标签中。让我们使用下面的库来构建一个裁剪器组件。

import { useCallback, useState } from "react";
import Cropper from "react-easy-crop";
import Modal from "../../Modal/Modal";

const ReactEasyCrop = ({ showModal, onModalClose, imgURL, onSaveHandler }) => {
    const [crop, setCrop] = useState({ x: 2, y: 2 });
    const [zoom, setZoom] = useState(1);
    const [croppedArea, setCroppedArea] = useState("");

    const onCropComplete = useCallback((croppedArea, croppedAreaPixels) => {
        setCroppedArea(croppedAreaPixels);
    }, []);
    const showCroppedImage = useCallback(async () => {
        try {
            const croppedImage = await getCroppedImg(imgURL, croppedArea, 0);
            return croppedImage;
        } catch (error) {
            console.error(error);
        }
    }, [croppedArea, imgURL]);

在上面的代码块中,我们创建了一个叫做ReactEasyCrop 的组件,它包含了像showModalonModalCloseimgURLonSaveHandlershowModal 的道具。

像其他图片裁剪器一样,showModalonModalClose 道具用于上传图片,而imgUrl 提供了我们要上传的图片的URL。

onCropComplete 允许我们保存图片的剪裁区域,并指定剪裁后的图片的像素或百分比大小。接下来,我们将使用Modal包装组件渲染我们的应用程序,如下图所示。

return (
                <Modal
                        showModal={showModal}
                        onSaveHandler={async () => onSaveHandler(await showCroppedImage())}
                        onModalClose={onModalClose}
                >
                        <div className="relative w-full">
                                <Cropper
                                        image={imgURL}
                                        crop={crop}
                                        zoom={zoom}
                                        aspect={4 / 3}
                                        onCropChange={setCrop}
                                        onCropComplete={onCropComplete}
                                        onZoomChange={setZoom}
                                />
                        </div>
                </Modal>
        );
};

export default ReactEazyCrop;

在上面的代码块中,我们将整个应用程序包裹在一个Modal 组件中,使我们能够上传我们的图像。接下来,我们初始化了Cropper 组件,在这里我们传递了我们裁剪后的图片的URL。

我们还添加了crop ,用来确定要裁剪的图片的位置。zoom ,用来放大图片,默认设置为1

onCropChange 用于更新我们应用程序的裁剪状态。当用户停止缩放图片时,onCropComplete 被调用。

总结

无论你在做什么类型的项目,裁剪器库都可以帮助你从照片上去除不需要的区域,从而改善你的整体用户界面。本教程中介绍的库有全面的内置功能,而且很容易定制。

现在,你应该能够为你的应用程序选择合适的裁剪器库了。我希望你喜欢这个教程