javascript - 在 React 中上传用户图像而不会造成质量损失
问题描述
我在一家已经实施了文件上传器的公司工作,但由于某种原因,我们正在保存照片并且其质量大大降低。基本上,我想知道最简单的方法是实现一个组件,用户可以在其中上传个人资料照片或徽标,我们可以在不损失质量的情况下保存它。我还希望能够在不损失质量的情况下将其调整为各种尺寸。我也不一定需要裁剪器,我希望用户能够上传照片并显示完整图像,只需调整大小而不会损失质量。Techstack 正在使用 JS 和 React。
class FileUpload extends React.Component {
constructor(props) {
super(props);
this.fileRef = createRef();
this.imgCanvas = createRef();
this.previousMoveX = 0;
this.previousMoveY = 0;
this.state = {
showUploadModal: false || props.showUploadModal,
img: '',
imgControl: false,
imgControlZoom: 0,
imgControlMove: false,
imgControlX: 0,
imgControlY: 0,
};
this.onImgRead = this.onImgRead.bind(this);
this.onChangeImage = this.onChangeImage.bind(this);
this.onChangeZoom = this.onChangeZoom.bind(this);
this.onStartMove = this.onStartMove.bind(this);
this.onMouseMove = this.onMouseMove.bind(this);
}
componentDidUpdate() {
const { img, imgControlZoom, imgControlX, imgControlY } = this.state;
if (img === '') return;
let canvas = this.imgCanvas.current;
if (canvas === null) return;
let ctx = canvas.getContext('2d');
let imgNode = new Image();
imgNode.onload = () => {
const s = parseInt(
Math.min(imgNode.width, imgNode.height) / ((imgControlZoom + 100) / 100)
);
const k = canvas.width / s;
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(
imgNode,
0,
0,
imgNode.width,
imgNode.height,
imgControlX + (s - imgNode.width) * 0.5 * k,
imgControlY + (s - imgNode.height) * 0.5 * k,
imgNode.width * k,
imgNode.height * k
);
};
imgNode.src = img;
}
onChangeImage(e) {
const input = e.target;
const { files } = e.target;
if (files === 0) return;
const file = files[0];
if (file.size > FILE_SIZE) {
toast.error(FILE_SIZE_VALIDATION);
return;
}
const fileReader = new FileReader();
fileReader.onload = ev => {
input.value = '';
this.onImgRead(ev.target.result);
};
fileReader.readAsDataURL(file, 'UTF-8');
}
解决方案
这与 React 无关,通常不会在客户端使用 JS 实现,除非您在服务器上使用 NodeJS。此功能通常在服务器上实现。比如nginx 的http_image_filter_module模块。
对于有损图像格式(如 jpeg),任何更改都会再次损失图像质量,尽管这种损失通常很小。如果你真的需要非常高质量的图片,你需要先在服务器上将它们转换成无损图片格式(比如png)。
推荐阅读
- java - 码头工人。驱动程序可执行文件不存在:/chromedriver.exe
- python - 我做文章的顶部?但是当我开始我的项目时,我遇到了错误 unhashable type: 'slice'
- ios - 使用 CoreData 在表格视图顶部插入新行
- wordpress - 如何用经典的帖子编辑器替换 woocommerce 编辑器?
- unity3d - 表面着色器输入结构中的 IN.worldRefl 是什么?
- javascript - 使用 lodash groupBy 函数对数组中的对象进行分类
- html - 标签为多行时未获取正确的规范 URL,如何在标签为多行时 grep 规范 URL?
- c++ - 关于 C++17 中的尾随返回类型的问题
- python - SpectralClustering 中的 fit() 和 fit_predict() 有什么区别
- javascript - 如何使用 map 函数使 const in react