С помощью React Avatar Editor получить круглую картинку, отправить её на сервер и сохранить там

173
28 декабря 2018, 15:20

React Avatar Editor.

Делаю как в пример:

<Dropzone
    onDrop={this.handleDrop}
    disableClick
    style={{ width: '250px', height: '250px' }}>
    <AvatarEditor
        ref={this.refAvatar}
        image={this.state.image}
        borderRadius={125}
        width={250}
        height={250}
        border={0}
        scale={1}
    />
</Dropzone> 

В редакторе всё выглядит правильно:

Обработка:

handleDrop = dropped => {
    this.setState({ image: dropped[0] })
};
onClickSave = () => {
    // This returns a HTMLCanvasElement, it can be made into a data URL or a blob,
    // drawn on another canvas, or added to the DOM.
    const canvas = this.refAvatar.current.getImage();
    // If you want the image resized to the canvas size (also a HTMLCanvasElement)
    const canvasScaled = this.refAvatar.current.getImageScaledToCanvas();
    const img = canvasScaled.toDataURL();
    const rect = this.refAvatar.current.getCroppingRect();
};

В итоге есть canvasScaled (тут кропнутая квадратная картинка) и rect.

А как дальше получить круглую картинку? В их демке в превью закруглённость получается за счёт css: border-radius: 52.5px;. Мне это не поможет получить круглую пикчу и отправить на сервер.

Answer 1
  1. Создал невидимый canvas.

    <canvas style={{display: "none"}}
        ref={this.refCanvas}
        width={250}
        height={250}
    />
  2. В него отрисовываю кропнутую квадратную картинку.
  3. Обрезаю всё, что вне круга.
  4. Получаю итоговое изображение.
  5. Отправляю на сервер.

Обработка теперь такая:

onClickSave = () => {
    const canvasScaled = this.refAvatar.current.getImageScaledToCanvas();
    const img = canvasScaled.toDataURL();
    const rect = this.refAvatar.current.getCroppingRect();
    this.drawPreview(img, rect);
};
drawPreview = (img, rect) => {
    const image = new Image();
    image.src = img;
    image.onload = _ => {this.handleImageLoad(image)};
};

handleImageLoad = (image) => {
    const ctx = this.refCanvas.current.getContext('2d');
    const width = 250;
    const height = 250;
    ctx.clearRect(0, 0, width, height);
    ctx.arc(125,125, 125, 0, Math.PI*2,true);
    ctx.clip();
    ctx.drawImage(image, 0, 0, width, height);
    axios.post('http://localhost:8081/upload', {img: this.refCanvas.current.toDataURL()}, {
        'Accept': 'application/json'
    }).then((response) => {
        console.log(response);
    })
        .catch(err => {
            console.log(err);
        });
};

На серваке обработка тривиальная, там express:

app.post('/upload', (req, res) => {
    const data = req.body.img.replace(/^data:image\/\w+;base64,/, "");
    const buf = new Buffer(data, 'base64');
    fs.writeFile(__dirname + '/../public/image.png', buf);
});

Картинка получается круглая:

READ ALSO