我正在使用react-image-crop with react和Express来上传配置文件pic

问题描述 投票:0回答:1

尝试使用https://www.npmjs.com/package/react-image-crop上传裁剪的图像。

并关注此https://codesandbox.io/s/72py4jlll6

我可以从src上传基本文件但注意裁剪图像src。谁能告诉我如何获取裁剪的图像并制作文件并上传。

这是我的ProfilePic组件现在 -

          import React, { Component } from "react";
          import { connect } from "react-redux";
          import PropTypes from "prop-types";
          import ReactCrop from "react-image-crop";
          import "react-image-crop/dist/ReactCrop.css";
          import { setProfilePic } from "../../actions/authAction";

          // https://codesandbox.io/s/72py4jlll6
          class ProfilePic extends Component {
            constructor(props) {
              super(props);
              this.state = {
                src: null,
                crop: { x: 10, y: 10, aspect: 1, width: 50 },
                selectedFile: null,
                croppedImageUrl: null
              };

              this.onProfileImageSubmit = this.onProfileImageSubmit.bind(this);
            }
            b64toBlob(b64Data, contentType, sliceSize) {
              contentType = contentType || "";
              sliceSize = sliceSize || 512;

              var byteCharacters = atob(b64Data);
              var byteArrays = [];

              for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
                var slice = byteCharacters.slice(offset, offset + sliceSize);

                var byteNumbers = new Array(slice.length);
                for (var i = 0; i < slice.length; i++) {
                  byteNumbers[i] = slice.charCodeAt(i);
                }

                var byteArray = new Uint8Array(byteNumbers);

                byteArrays.push(byteArray);
              }

              var blob = new Blob(byteArrays, { type: contentType });
              return blob;
            }
            onProfileImageSubmit(e) {
              e.preventDefault();

              var ImageURL = this.state.src;
              var block = ImageURL.split(";");
              var contentType = block[0].split(":")[1];
              var realData = block[1].split(",")[1];
              var blob = this.b64toBlob(realData, contentType);

              console.log(blob);

              const data = new FormData();

              data.append("profilePic", blob);
              this.props.setProfilePic(data);
            }
            onSelectFile = e => {
              this.setState({ selectedFile: e.target.files });
              if (e.target.files && e.target.files.length > 0) {
                const reader = new FileReader();
                reader.addEventListener("load", () =>
                  this.setState({ src: reader.result })
                );
                reader.readAsDataURL(e.target.files[0]);
              }
            };

            onImageLoaded = (image, pixelCrop) => {
              this.imageRef = image;

              // Make the library regenerate aspect crops if loading new images.
              const { crop } = this.state;

              if (crop.aspect && crop.height && crop.width) {
                this.setState({
                  crop: { ...crop, height: null }
                });
              } else {
                this.makeClientCrop(crop, pixelCrop);
              }
            };

            onCropComplete = (crop, pixelCrop) => {
              this.makeClientCrop(crop, pixelCrop);
            };

            onCropChange = crop => {
              this.setState({ crop });
            };

            async makeClientCrop(crop, pixelCrop) {
              if (this.imageRef && crop.width && crop.height) {
                const croppedImageUrl = await this.getCroppedImg(
                  this.imageRef,
                  pixelCrop,
                  "newFile.jpeg"
                );

                this.setState({ croppedImageUrl });
              }
            }

            getCroppedImg(image, pixelCrop, fileName) {
              const canvas = document.createElement("canvas");
              canvas.width = pixelCrop.width;
              canvas.height = pixelCrop.height;
              const ctx = canvas.getContext("2d");

              ctx.drawImage(
                image,
                pixelCrop.x,
                pixelCrop.y,
                pixelCrop.width,
                pixelCrop.height,
                0,
                0,
                pixelCrop.width,
                pixelCrop.height
              );

              return new Promise((resolve, reject) => {
                canvas.toBlob(blob => {
                  blob.name = fileName;
                  window.URL.revokeObjectURL(this.fileUrl);
                  this.fileUrl = window.URL.createObjectURL(blob);
                  resolve(this.fileUrl);
                }, "image/jpeg");
              });
            }
            render() {
              const { croppedImageUrl } = this.state;
              return (
                <div>
                  <div
                    className="modal fade"
                    id="update-header-photo"
                    tabindex="-1"
                    role="dialog"
                    aria-labelledby="update-header-photo"
                    aria-hidden="false"
                  >
                    <div
                      className="modal-dialog window-popup update-header-photo"
                      role="document"
                    >
                      <div className="modal-content">
                        <a
                          href="#"
                          className="close icon-close"
                          data-dismiss="modal"
                          aria-label="Close"
                        >
                          <i class="fa fa-user mr-3" aria-hidden="true" />
                        </a>
                        <div className="modal-header">
                          <h6 className="title">Update Header Photo</h6>
                        </div>
                        <div className="modal-body">
                          <a
                            href="#"
                            className="upload-photo-item"
                            style={{ width: "100%" }}
                          >
                            <form onSubmit={this.onProfileImageSubmit}>
                              <div>
                                <input
                                  type="file"
                                  onChange={this.onSelectFile}
                                  name="profilePic"
                                />
                              </div>
                              {this.state.src && (
                                <ReactCrop
                                  src={this.state.src}
                                  crop={this.state.crop}
                                  onImageLoaded={this.onImageLoaded}
                                  onComplete={this.onCropComplete}
                                  onChange={this.onCropChange}
                                />
                              )}
                              {croppedImageUrl && (
                                <img alt="Crop" src={croppedImageUrl} />
                              )}

                              <h6>Upload Photo</h6>
                              <span>Browse your computer.</span>
                              <input
                                className="btn btn-primary btn-lg full-width"
                                type="submit"
                                value="save"
                              />
                            </form>
                          </a>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              );
            }
          }
          export default connect(
            null,
            { setProfilePic }
          )(ProfilePic);
javascript reactjs mongodb express
1个回答
0
投票

在getCroppedImg()函数中添加this.setState({blob:blob})

canvas.toBlob(blob => {
    blob.name = fileName;
    window.URL.revokeObjectURL(this.fileUrl);
    this.fileUrl = window.URL.createObjectURL(blob);
    resolve(this.fileUrl);
    this.setState({blob:blob}) //added by SO huy nguyen 
}, "image/jpeg");

并修改onProfileImageSubmit()

onProfileImageSubmit(e) {
  e.preventDefault();           
  const data = new FormData();
  data.append("profilePic", this.state.blob);
  this.props.setProfilePic(data);
}

我们不需要将base64转换为Blob。

© www.soinside.com 2019 - 2024. All rights reserved.