One, foreword

Why choose to usereact-avatar-editorThis plugin?

Since WE are writing mobile projects with React, one of the requirements is to create an avatar cropping function (you can select images to crop locally or pull remote images to crop).

So I went to GitHub to find relevant plug-ins. According to the amount of star, find the following plug-ins.

So why do I use react-Avatar-editor?

1. The End of the Road

Facebook like, avatar / profile picture component. Resize, crop and rotate your uploaded image using a clear user interface.

2. Why?

  • Small enough (only a few hundred k ah! Hello!)
  • Convenient extension
  • Issues less (😂 only one 1 issue ah!
  • Mobile terminal support
  • Convenient compression

Second, the use of

The installation

npm install --save react-avatar-editor
Copy the code

Officials in the column

import React from 'react' import AvatarEditor from 'react-avatar-editor' class MyEditor extends React.Component { render() { return ( <AvatarEditor image="http://example.com/initialimage.jpg" width={250} height={250} border={50} Color ={[255, 255, 255, 0.6]} // RGBA scale={1.2} rotate={0} />)}} export default MyEditorCopy the code

The official demo

Props

Worthy of attention:

  • image

  • crossOrigin

These two props are the key for me to pull remote pictures and cut them out. There is basically no problem with other props as long as they follow the official instructions

pit

I started by finishing the local selection of picture cropping, and then connect to the image upload interface directly successful. But the console gave me an unintended error when I called Cancanvas. ToDataURL () after I clipped the remote image.

Uncaught DOMException: Failed to execute ‘toDataURL’ on ‘HTMLCanvasElement’: Tainted canvases may not be exported.

????? What the hell??

The effect is

Unable to perform ‘toDataURL’ on ‘HTMLCanvasElement’ : Contaminated canvas may not be exported.

At this point, I didn’t know what was wrong, so I silently went to Google, after a meal of operation, know

Since pixels in a < Canvas > bitmap can come from multiple sources, including images or videos retrieved from other hosts, security issues inevitably arise.

Although it is possible to use images from other sources in < Canvas > without using CORS, this taints the canvas and is no longer considered a safe canvas, which can throw exceptions during data retrieval in <canvas>.

Using “hard-coded” image urls makes it easy to allow images to come from any address. When we start downloading images, we use the Image() constructor to create a new HTMLImageElement object and set the Image’s crossOrigin property to “anonymous” (that is, to allow cross-domain downloading of unauthenticated images). Add a listener for the image load (en-US) event to determine whether the image data has been received. Finally, set the SRC (en-us) property of the image to the URL of the image to trigger the image download.

So that’s it! Isn’t there a crossOrigin property in front of it? On the whole!

The plugin source code reads like this:

export default function loadImageURL(imageURL, crossOrigin) {
  return new Promise((resolve, reject) => {
    const image = new Image()
    image.onload = () => resolve(image)
    image.onerror = reject
    if (isDataURL(imageURL) === false && crossOrigin) {
      image.crossOrigin = crossOrigin
    }
    image.src = imageURL
  })
}
Copy the code

Done! The refresh!

Why can’t you visit ??????

So I took a closer look at the MDN documentation: images with CORS enabled

It turned out that the server configuration was also required.

<IfModule mod_setenvif.c> <IfModule mod_headers.c> <FilesMatch "\.(cur|gif|ico|jpe? g|png|svgz? |webp)$"> SetEnvIf Origin ":" IS_CORS Header set Access-Control-Allow-Origin "*" env=IS_CORS </FilesMatch> </IfModule> </IfModule>Copy the code

Thinking and extension

The principle of picture cropping

At this time ACTUALLY I was a little fuzzy, so I went to check my database, remembered zhang Xinxu god in 18 years wrote an article “picture pure front-end JS compression implementation” specific content I will not repeat here. The general idea is:

That’s using the canvas drawImage() method. Canvas is essentially a bitmap, and the drawImage() method can draw a large image on a small Canvas, which is equivalent to image size compression

If you want to upload/download an image, you can use:

  • Canvas. ToDataURL () into base64
  • Canvas.toblob () is converted to a binary file

The last

Write for the first time, pure record, welcome to put forward opinions, welcome to discuss 👏, do not spray.