限制反应拖放区中的图像尺寸



我正在使用react-dropzone进行图像上传。一切正常。图像大小的验证也工作正常。但是我无法检查图像的尺寸。我想验证图像的宽度和高度,以强制用户在指定的宽度和高度之间上传图像。我试过image.addEventListener('load')但这不起作用。

这是我所做的

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";
};

您永远不会为图像设置src,因此事件处理程序永远不会触发。尝试设置image.src = URL.createObjectURL(file)。文件加载后,您的"加载"处理程序将触发。

尝试更改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)
})

如果要在onDrop之前验证维度,可以使用如下所示的getFilesFromEventvalidator回调。

优点与 maxSize 和接受等错误一样,您可以从rejectedFiles中获取卡在验证中的文件。

缺点是,如果您使用的是打字稿,则必须消除任何类型的类型错误。

const {
isDragActive,
getRootProps,
getInputProps,
isDragReject,
rejectedFiles
} = useDropzone({
getFilesFromEvent: async (event) => {
const files = event.target.files || event.dataTransfer.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
}
});

最新更新