简体   繁体   English

限制 react-dropzone 中的图像尺寸

[英]restrict image dimension in react-dropzone

I am using react-dropzone for image upload.我正在使用 react-dropzone 进行图像上传。 Everything is working fine.一切正常。 Validation for image size is also working fine.图像大小的验证也工作正常。 But I could not check the dimension for image.但我无法检查图像的尺寸。 I want to validate the image's width and height to enforce user to upload the image in between those specified width and height.我想验证图像的宽度和高度以强制用户在指定的宽度和高度之间上传图像。 I tried image.addEventListener('load') but this is not working.我试过image.addEventListener('load')但这不起作用。

Here is what I have done这是我所做的

export const UploadField = ({ preview, label, uploadProps, ...props }) => {
  const {
    input: { onChange },
    disabled
  } = props;

  const {
    isDragActive,
    getRootProps,
    getInputProps,
    isDragReject,
    rejectedFiles
  } = useDropzone({
    onDrop: files => {
      onChange(
        files.map(file => {
          const image = new Image();
          image.addEventListener("load", () => {
            console.log("image", image);
          });
          return Object.assign(file, {
            preview: URL.createObjectURL(file)
          });
        })
      );
    },
    ...uploadProps
  });

  const isFileTooLarge =
    rejectedFiles.length > 0 && rejectedFiles[0].size > uploadProps.maxSize;

  const files = props.input.value;

  if (disabled) {
    return null;
  }

  return (
    <>
      {label && <Label>{label}</Label>}
      <DropzoneContainer {...getRootProps()}>
        <input {...getInputProps()} />
        {!isDragActive && "Click here or drop a file to upload!"}
        {isDragActive && !isDragReject && "Drop it like it's hot!"}
        {isDragReject && "File type not accepted, sorry!"}
        {isFileTooLarge && (
          <div className="text-danger mt-2">File is too large.</div>
        )}
      </DropzoneContainer>
      <div>
        {files && files !== undefined ? (
          <>
            <Preview files={files} isLocal />
          </>
        ) : (
          <Preview files={preview} isLocal={false} />
        )}
      </div>
    </>
  );
};

export default UploadField;

UploadField.defaultProps = {
  uploadProps: {
    accept: "image/*",
    multiple: false,
    minSize: 0,
    maxSize: 5242880
  }
};

const DropzoneContainer = styled.div`
  width: 100%;
  padding: 14px;
  border-width: 2px;
  border-radius: 2px;
  border-color: ${props => getColor(props)};
  border-style: dashed;
  background-color: #fafafa;
  color: #bdbdbd;
  outline: none;
  transition: border 0.24s ease-in-out;
`;

const getColor = props => {
  if (props.isDragAccept) {
    return "#00e676";
  }
  if (props.isDragReject) {
    return "#ff1744";
  }
  if (props.isDragActive) {
    return "#2196f3";
  }
  return "#eeeeee";
};

You never set the src for the image so your event handler never fires.您永远不会为图像设置src ,因此您的事件处理程序永远不会触发。 Try setting image.src = URL.createObjectURL(file) .尝试设置image.src = URL.createObjectURL(file) Once the file loads, your 'load' handler will fire.文件加载后,您的“加载”处理程序将触发。

Try changing the contents of your onDrop callback to include this:尝试更改onDrop回调的内容以包含以下内容:

const filteredImages = [];
let counter = 0;

files.map(file => {
    const image = new Image();
    image.addEventListener('load', () => {
        console.log(`${image.width}x${image.height}`)

        // only select images within width/height limits
        if (image.width < WIDTH_LIM & image.height < HEIGHT_LIM) {
            filteredImages.push(image)
        }

        // increment counter for each image we go through
        counter += 1;

        // if we have gone through all the files, handle the ones that
        // made it through the filter using `handleImages` function
        if (counter === files.length) handleImages(filteredImages);
    });
    image.src = URL.createObjectURL(file)
})

If you want to validate dimensions before onDrop , you can use getFilesFromEvent and validator callbacks like below.如果您想在onDrop之前验证维度,您可以使用getFilesFromEvent和如下所示的validator回调。

Pros As with errors such as maxSize and accept, you can get files that are stuck in validation for dimention from rejectedFiles .优点与错误,如MAXSIZE和接受,你可以得到被困在验证从渔政船的文件rejectedFiles

Cons f you are using typescript, you have to eliminate the type error with any type.缺点如果您使用打字稿,则必须消除任何类型的类型错误。

const {
    isDragActive,
    getRootProps,
    getInputProps,
    isDragReject,
    rejectedFiles
  } = useDropzone({
    getFilesFromEvent: async (event) => {
      const files = event.target.files
      const promises = []
      for (let index = 0; index < files.length; index++) {
        const file = files[index]
        const promise = new Promise((resolve, reject) => {
          const image = new Image()
          let url: string
          image.onload = function () {
            file.width = image.width
            file.height = image.height
            resolve(file)
          }
          url = URL.createObjectURL(file)
          image.src = url
        })
        promises.push(promise)
      }
      return await Promise.all(promises)
    },
    validator: (file) => {
      // You can access width/height properties
      if(file.width < MIN_WIDTH) {
        return {
          code: "small-width",
          message: `Image width must be greater than ${MIN_WIDTH}`,
        }
      }
      return null
    }

  });



声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM