React中如何压缩摄像头获取的Base64 JPEG图片?
解决react-webcam获取的Base64图片无法用browser-image-compression压缩的问题
核心问题是react-webcam的getScreenshot()返回Base64格式字符串,而browser-image-compression要求输入为Blob/File类型。只需实现一个Base64转Blob的工具函数,就能解决这个问题。
1. 实现Base64转Blob函数
Base64字符串包含前缀(如data:image/jpeg;base64,),需先剥离前缀,再将编码字符串解码为二进制数据,最后生成Blob对象:
const base64ToBlob = (base64Str) => { // 拆分Base64前缀与编码内容 const [prefix, encodedStr] = base64Str.split(','); // 提取图片MIME类型 const mimeType = prefix.match(/:(.*?);/)[1]; // 解码Base64为二进制字符 const byteCharacters = atob(encodedStr); const byteArrays = []; for (let i = 0; i < byteCharacters.length; i++) { byteArrays.push(byteCharacters.charCodeAt(i)); } return new Blob([new Uint8Array(byteArrays)], { type: mimeType }); };
2. 修改原代码集成压缩逻辑
在capture函数中先将Base64转为Blob,再传入压缩库处理,最后用FormData将压缩后的Blob发送至后端:
import Webcam from "react-webcam" import React, { useRef } from "react" import imageCompression from "browser-image-compression" const App = () => { const webRef = useRef(null) const base64ToBlob = (base64Str) => { const [prefix, encodedStr] = base64Str.split(','); const mimeType = prefix.match(/:(.*?);/)[1]; const byteCharacters = atob(encodedStr); const byteArrays = []; for (let i = 0; i < byteCharacters.length; i++) { byteArrays.push(byteCharacters.charCodeAt(i)); } return new Blob([new Uint8Array(byteArrays)], { type: mimeType }); }; const capture = async () => { const base64Img = webRef.current.getScreenshot(); if (!base64Img) return; // 转换Base64为Blob const imgBlob = base64ToBlob(base64Img); // 压缩配置 const options = { maxSizeMB: 0.5, maxWidthOrHeight: 720, useWebWorker: true, fileType: 'image/jpeg' // 可替换为image/webp获得更高压缩率 }; try { const compressedImage = await imageCompression(imgBlob, options); // 包装为FormData准备上传 const formData = new FormData(); formData.append('image', compressedImage, 'compressed-capture.jpg'); // 发送到后端API示例 await fetch('/your-backend-api-url', { method: 'POST', body: formData }); console.log('图片上传成功'); } catch (error) { console.error('压缩或上传失败:', error); } } return ( <> <div className="webcam-container"> <Webcam ref={webRef} mirrored={true} screenshotQuality={0.5} className="webcam" audio={false} screenshotFormat="image/jpeg" width={720} height={720} /> <div className="webcam-button-container"> <button onClick={capture}>Capture</button> </div> </div> </> ) } export default App
额外优化建议
- 若追求更高压缩效率,可将
options中的fileType设为image/webp,WebP格式在相同画质下体积远小于JPEG。 - 可在压缩前判断原图片大小,若已小于目标阈值,直接跳过压缩步骤提升性能。
内容的提问来源于stack exchange,提问作者nzy
相关产品推荐
相关产品推荐

