You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 22:10:43