如何在React.js中创建图像处理和裁剪组件

99 阅读7分钟

在React.js中创建图像处理和裁剪组件

媒体管理是动态内容网站(如博客、社交媒体网站和娱乐网站)的主要焦点。随着用户媒体上传量的急剧上升,平台必须适应不断变化的行为,并减少服务器的使用和成本。

前端网络开发中处理媒体(图片)文件的一种方式是裁剪和压缩做法。React.js和vanilla CSS可以成为在前端Web开发中处理媒体和多媒体文件的一个强大组合。

在本教程中,我们将讨论在React.js中创建图像处理器和裁剪器所需的操作、逻辑和依赖性。我们还将研究如何用CSS优化图片显示。

主要收获

在本教程结束时,读者将了解。

  • 开始了解React.js的开发周期。
  • 用React.js创建一个图像裁剪组件。
  • 在React.js中限制可卸载文件的数量和大小。
  • 用React.js和CSS进行图像压缩。
  • 图像管理中的错误处理。

前提条件

要跟上本教程,需要有React.js和CSS的基本知识。此外,我建议使用Visual Studio Code作为首选文本编辑器。

开始使用React.js开发周期

React的开发周期是非常直接的。React让你在一个干净的板块上开始你的代码片段,并安装了所有的默认依赖项。一个简单的bash命令将为你启动react-app

在你的电脑上打开命令终端,运行下面的命令来创建一个新的React应用程序。

npx create-react-app image-app-demo

Yarn用户可以使用。

yarn create-react-app image-app-demo

该命令需要几分钟时间来安装和设置你的新React应用程序所需的所有默认包。该操作需要互联网连接,所以确保你的Wi-Fi或调制解调器已连接。

一旦这个过程完成,我们将启动开发服务器,通过运行下面的命令来实时查看应用程序的情况。

cd image-app-demo
npm start

对于yarn用户。

cd image-app-demo
yarn start

如果正确执行,一个新的标签将在你的默认浏览器上打开,一个React登陆页面将显示在http://localhost:3000。

React.js中的图像优化

对前端Web开发者来说,图像优化涉及到用于改善图像渲染和上传的各种技术。它涉及裁剪、压缩、调整大小和其他最佳实践。

我们将在这篇文章中研究裁剪和压缩技术。我们将通过执行以下内容的步骤和过程。

  • 用React和react-image-crop 构建一个图像裁剪组件。
  • 如何勾勒出允许的文件类型。
  • 使用FileReader 作为预览图片的替代方法。
  • 在React.js中防止多文件上传。
  • 用React.js和CSS调整图片大小。

用React.js创建图片裁剪组件

图片裁剪可以通过大量的代码和操作来完成,但我们有一个包的依赖性,可以减少图片裁剪的负担。react-image-crop 包被证明在前端图像裁剪中是有效的。

第1步 - 安装 react-image-crop 依赖项

为了在我们的项目中安装react-image-crop 包,我们打开command terminal ,运行下面的命令来安装它。

npm install react-image-crop

对于yarn用户。

yarn add react-image-crop

一旦完成,我们将在我们的项目中导入并使用该包。

第2步 - 设置裁剪组件(App.js)。

该组件将允许用户从他们的本地设备中选择一个图像文件。此后,用户可以继续将图片裁剪成他们想要的尺寸。

本文不涉及上传裁剪后的图片,但Cloudinary等平台提供了基于云的服务,你可以利用这些服务来上传图片。请随意查看他们的免费和付费服务。

要创建一个图像裁剪组件,在App.js 文件中,粘贴下面的代码片段。

import React, { useState } from "react";
import ReactCrop from "react-image-crop";

export function ImageCropper() {
  const allowedFileTypes = `image/gif image/png, image/jpeg, image/x-png`;
  const [viewImage, setViewImage] = useState(undefined);
  const [crop, setCrop] = useState({
    aspect: 1 / 1,
    height: 468,
    unit: "px",
    width: 468,
    x: 0,
    y: 107,
  });
  const [image, setImage] = useState(undefined);
  const [imageUrl, setImageUrl] = useState(undefined);

  const handleFileChange = (e) => {
    let image = e.target.files[0];
    if (image) {
      const imageReader = new FileReader();
      imageReader.readAsDataURL(image);
      imageReader.onloadend = () => {
        setViewImage(imageReader.result);
      };
    }
  };
  const imageLoaded = (image) => {
    setImage(image);
  };
  function imageCrop(crop) {
    setCrop(crop);
  }
  function imageCropComplete(crop) {
    userCrop(crop);
  }
  async function userCrop(crop) {
    if (image && crop.width && crop.height) {
      await getCroppedImage(image, crop, "newFile.jpeg");
    }
  }
  function getCroppedImage(image, crop, fileName) {
    const imageCanvas = document.createElement("canvas");
    const scaleX = image.naturalWidth / image.width;
    const scaleY = image.naturalHeight / image.height;
    imageCanvas.width = crop.width;
    imageCanvas.height = crop.height;
    const imgCx = imageCanvas.getContext("2d");
    imgCx.drawImage(
      image,
      crop.x * scaleX,
      crop.y * scaleY,
      crop.width * scaleX,
      crop.height * scaleY,
      0,
      0,
      crop.width,
      crop.height
    );
    return new Promise((reject, resolve) => {
      imageCanvas.toBlob((blob) => {
        if (!blob) {
          reject(new Error("the image canvas is empty"));
          return;
        }
        blob.name = fileName;
        let imageURL;
        window.URL.revokeObjectURL(imageURL);
        imageURL = window.URL.createObjectURL(blob);
        resolve(imageURL);
        setImageUrl(blob);
      }, "image1/jpeg");
    });
  }

  return (
    <>
      <label htmlFor="upload-image">
        <input
          style={{ display: "none" }}
          id="upload-image"
          name="upload photo"
          type="file"
          multiple={false}
          accept={allowedFileTypes}
          onChange={handleFileChange}
        />
        <button
          className="upload-btn"
          variant="contained"
          component="span"
        ></button>
      </label>
      <ReactCrop
        src={viewImage}
        crop={crop}
        onImageLoaded={imageLoaded}
        onChange={imageCrop}
        onComplete={imageCropComplete}
      />
    </>
  );
}

从上面的代码片断,我们。

  • 从先前安装的react-image-crop 包中导入并使用了ReactCrop
  • 使用了一个input 标签,允许用户选择一个文件进行裁剪。
  • 为了防止选择多个文件,我们添加了multiple={false} 标志。
  • 创建了allowedFileTypes 常量来指定用户可以上传的文件类型,包括gif、png、jpeg和x-png。
  • 定义了一些默认参数,如aspect,height,unit,width 等,我们将在图像裁剪和重建过程中使用这些参数。
  • 我们还创建了一些函数,其中包括接受文件的handleFileChange 。在FileReader 方法的帮助下,我们将图像加载到ReactCrop 组件中进行裁剪。

代码片段的第二部分涵盖了裁剪操作。在该部分,我们做了以下工作。

  • 创建了imageLoaded 函数,以加载并获得准备用于裁剪的图像。
  • 我们还创建了userCrop 函数,接受用户提供的裁剪尺寸,即cropHeightcropWidth ,这将通过调整屏幕上显示的裁剪线来提供。
  • 一旦用户设定了裁剪尺寸,getCroppedImage 函数就会接收新的图像数据(文件名、裁剪和图像)。这将被用来重建最终的图像,以便上传。这个过程是通过一个二维画布实现的,它被用来在React.js中生成、操作和渲染图形元素。
  • 最后,用画布中提供的尺寸和图像元数据按比例绘制新的图像。如果没有发生错误,一个新的文件名(image1.jpeg)会附加到图像上并显示出来。

保存更改并打开浏览器,测试一下ImageCropper

用CSS优化和调整图像大小

大型图像文件的显示可能超出允许的容器尺寸,从而扭曲了页面布局。如果不勾选,图像溢出也可能显示在另一个页面元素的上面,我们不希望这种情况发生。

优化和减少图像文件大小的一个简单的CSS技巧是进行调整大小的操作。另外,隐藏图像溢出有助于检查超大的图像显示。

让我们运行一个示例代码片断来展示它是如何实现的。

import React from "react";
import './App.css'

function imageResize() {
  return (
    <div className="image-container">
      <h3 classname="page-header"></h3>
      <img
      className='display-image'
        src="https://www.pexels.com/photo/red-field-summer-agriculture-70741/"
        alt="medium size flower image"
      />
    </div>
  );
}

export default imageResize;

从上面的代码片断中,我们复制了一张大图片的URL,并使用Reactimg 标签显示。我们将classNames 赋给div 容器和img 标签,我们将应用一些CSS样式。

在CSS文件(App.css)中,复制并粘贴下面的代码片段。

.image-container {
  height: 100%;
  width: 100%;
  justify-content: center;
}
.page-header{
  font-size: large;
  font-weight: bold;
  text-decoration: none;
}
.display-image img {
  width: auto;
  height: 100%;
  object-fit: contain;
  overflow: hidden;
}

在上面的CSS代码段中,我们把先前分配给我们的页面元素的classNames ,并添加了一些样式。我们通过添加overflow:hidden 标志,防止图像溢出到容器之外。

最后,我们调整了图片heightwidth 的大小,以确保它能正常显示。

总结

在这篇文章中,我们使用了React.js和react-image-crop 包来创建一个图像裁剪组件。这个组件能够将图片裁剪成用户需要的大小。我们还研究了如何指定用户可以上传的可接受的文件类型,并防止多个文件的选择。

最后,我们探讨了在CSS中优化图像显示的方法。我希望这篇文章对你的网络开发之旅有帮助。