Recently, the company developed the management function of the cast image. In order to make the uploaded image conform to the size of the cast image, the image needs to be cut to a certain scale before uploading. Here is a record of antD’s Upload component and React-Cropper to implement the cropping Upload function.

1. Install the React-Cropper plug-in

yarn add react-cropper
// or npm install react-cropper --save
Copy the code

2. Implementation idea

  • When uploading using ANTD’s Upload component, you need to read the image with FileReader before uploading, save a Base64 string in data: URL format to represent the content of the file being read, and return false in the beforeUpload function to prevent the image from being uploaded.

  • The Copper component accepts parameters such as the length/width of the clipping box and the size of the clipping area.

  • After taking a screenshot with Coppper, click ok, use Cropper’s getCroppedCanvas method to convert the clipped area data to canvas data, and then call the browser’s native toBlob method to convert canvas data toBlob data. Finally, the BLOB data is sent to the back end.

3. Specific code implementation


import React, { PureComponent } from 'react';
import { Button, Form, Row, Col, Drawer, Upload, Icon, Modal, notification } from 'antd';
import 'cropperjs/dist/cropper.css';
import Cropper from 'react-cropper';

export default class RenderDrawer extends PureComponent {
  super(props);
    this.state = {
      previewVisible: false.// Preview the modal box
      previewImage: ' '.// Preview the image address
      srcCropper: ' '.// The current image path
      selectImgName: ' '.// The current file name
      editImageModalVisible: false.// Trim the modal box
      saveImgLoading: false.// Save the clipped image loading
    };

      // Upload function called before component image is uploaded
    uploadBefore = file= > {
      // 1. Verify file size
      const fileSize = maxFileSize * 1024 * 1024;
      if (file.size > fileSize) {
          file.status = 'error'; // eslint-disable-line
          file.response = 'Upload file size cannot exceed:${fileSize / (1024 * 1024)}MB`; // eslint-disable-line return false; } // 1. FileReader // - FileReader objects allow Web applications to asynchronously read the contents of files (or raw data buffers) stored on the user's computer, using File or Blob objects to specify files or data to read. // - Event filereader. onload, which fires when the read operation is complete/ - const reader = new FileReader(); /The/Image() function creates a new HTMLImageElement instance, Image(width, height) // Document.createElement ('img') const image = new image (); reader.readAsDataURL(file); // starts reading the contents of the specified Blob. Once complete, the Result property contains a Base64 string in data: URL format to represent the contents of the file being read. // 1. img.onload // -img. onload is a callback function that is executed when img is loaded/ - When the SRC of the image is changed, the browser will run to load the resources in this SRC. This operation is asynchronous, that is, instead of sitting around waiting for the image to load, the JS will continue to read the code until the image is loaded and the onload event is triggered, and then the JS will come back and execute the onload. // 2. reader.onload // - A load event is triggered when FileReader reads a file as readAsArrayBuffer, readAsBinaryString, readAsDataURL, or readAsText. The event can then be processed using the Filereader.onload attribute. reader.onload = e => { /The/onload event is executed immediately after the image is loaded. image.src = reader.result; image.onload = () => { this.setState({ srcCropper: e.target.result, /SelectImgName: file.name, // File name // selectImgSize: file.size / 1024 / / 1024/ File size // selectImgSuffix: file.type.split('/')[1], // file type editImageModalVisible: true, // Open the variable that controls cropping popover, true is popover}); }; }; return false; // Return false to prevent file upload}; // save the clipped image handleSaveImg = () => {const {dispatch} = this.props; const { selectImgName } = this.state; if (this.state.srcCropper) { this.setState({ saveImgLoading: true }); // the getCroppedCanvas method converts the clipped area data to canvas data // then calls the browser's native toBlob method to convert canvas data toBlob data this.cropper.getCroppedCanvas().toBlob(blob => { const formData = new FormData(); Formdata.append (name, value, filename); Vlaue only supports blob string File formdata.append ('file', blob, selectImgName); // Then send the bloB data to the back-end dispatch({type: 'manageMarquee/uploadImage', payload: formData, }).then(res => { if (res && ! res.failed) { this.setState({ saveImgLoading: false, editImageModalVisible: false, fileList: [ { uid: -1, name: res.fileName, status: 'done', url: res.fileUrl, }, ], }); Notification. success({message: upload successfully! }); }}); }); }}; render() { const { srcCropper = '', saveImgLoading = false, fileList = [] } = this.state; const fileProps = { showDownloadIcon: true, showPreviewIcon, fileListMaxLength: 1, fileList, action: 'plugin/address', accept: ['image/jpeg', 'image/jpg', 'image/png'], headers: { Authorization: `Bearer ${cookieToken}`, }, beforeUpload: this.uploadBefore, onPreview: this.setState({previewVisible: true}); onRemove: () => { this.setState({ fileList: [], }); }}; Return (<> // antD 
        
          {fileList.length >= 1 ? null : (
         
upload
)} // Trim Modal box this.setState({ editImageModalVisible: false })} title='
Select the clipping areaFooter ={[{this.cropper ={this.cropper ={this.cropper ={this.cropper ={this.cropper ={this.cropper ={this.cropper; }} preview=". UploadCrop "viewMode={1} // define cropper zoomable={false} // movable guides={false} // The dotted line displayed above the cropping box background={false} // Whether to display the background Mosaic Rotatable ={false} // Whether to rotate autoCropArea={1} // Default value 0.8 (80% of the image). Style ={{width: '100%', height: '400px'}} aspectRatio={1152/382} The default is free scale // cropBoxResizable={false} // The default is true, whether dragging is allowed to change the clipping box size // cropBoxMovable // Whether dragging clipping box is allowed the default is true dragMode="move" // When the mouse clicks on a point, a crop box is regenerated based on that point. Move can drag an image, None: Images cannot drag center /> // Preview Modal box {this.setState({previewVisible: false})}}> 100%' }} src={previewImage} /> ) } }
Copy the code

4. Achieve results

5. Add

1. FileReader method

Refer to the article www.cnblogs.com/dongxixi/p/…

  • ReadAsText reads files in characters, so for text files, it only needs to read the specified encoding. For media files (images, audio, video), their internal composition is not arranged in character, so readAsText will generate garbled characters, and it is not the best way to read the file

  • ReadAsDataURL base64 encodes the contents of the file for output

  • ReadAsBinaryString Unlike readAsText, the readAsBinaryString function reads the contents of the file by byte. Whereas binary data such as 0101 is only machine-readable and needs to be encoded once to be visible, the result of readAsBinaryString is to read the binary and encode its contents. Although the readAsBinaryString method can read files by byte, it is not suitable for direct transfer and is not recommended because the read content is encoded as characters, which affect the size. For example, the test image file was originally 6764 bytes, but was expanded to 10092 bytes after being read by readAsBinaryString

2. FileReader application

We know that the SRC property of img or the URL property of background can display an image by being assigned to the image network address or Base64. In file uploading, we usually upload local files to the server first. After successful uploading, the background will return the network address of the picture and then display it in the front end. With FileReader’s readAsDataURL method, you can display local images directly on the page without going through the background. This can reduce the frequent interaction between the front and back ends and reduce the useless image resources on the server side

For picture uploading, we can also convert the picture to Base64 for transmission first. At this time, as the transmitted picture content is a string, the upload interface can be treated as a common POST interface. When the picture is transferred to the background, it can be converted into a file entity for storage. Of course, considering the base64 conversion efficiency and its size, this method is suitable for uploading simple content or small memory files.

3. Upload files using the FormData object

The FormData interface provides a way to construct key-value pairs representing FormData, and when using the append() method, the content-disposition header that sends the request specifies the filename with a third optional parameter. If no filename is specified (or if this parameter is not supported), the name “blob” is used

4. ToDataURL toBlob

Both the toBlob() and toDataURL() methods are available, but I personally recommend using the toBlob() method