React.js:应用 CSS 过滤器后下载图像

React.js: Downloading image after applying CSS filters

问题

我正在制作一个编辑图像的应用程序,但在应用滤镜后下载图像时卡住了。正如预期的那样,用户可以拖放(或仅上传)图像(在 Cloudinary 上创建动态 URL)并将 CSS 过滤器应用于上传的图像。

所以,基本上,我想将图像保存到 Cloudinary API,但还要应用滤镜。

️建筑

Edite web app architecture or more about here

⚙️重现问题

您可以通过克隆 Edite GitHub repository and following the guide 来设置服务来重现此问题。

代码

注: 看到src是根

components/Toolbar/Right/options.json

[
  {
    "property": "brightness",
    "value": 100,
    "range": {
      "min": 0,
      "max": 100
    },
    "unit": "%"
  },
  {
    "property": "contrast",
    "value": 100,
    "range": {
      "min": 0,
      "max": 200
    },
    "unit": "%"
  },
  {
    "property": "saturate",
    "value": 100,
    "range": {
      "min": 0,
      "max": 200
    },
    "unit": "%"
  },
  {
    "property": "grayscale",
    "value": 0,
    "range": {
      "min": 0,
      "max": 100
    },
    "unit": "%"
  },
  {
    "property": "sepia",
    "value": 0,
    "range": {
      "min": 0,
      "max": 100
    },
    "unit": "%"
  },
  {
    "property": "invert",
    "value": 0,
    "range": {
      "min": 0,
      "max": 100
    },
    "unit": "%"
  },
  {
    "property": "hue-rotate",
    "value": 0,
    "range": {
      "min": 0,
      "max": 360
    },
    "unit": "deg"
  }
]

components/FileUploader/index.js

function FileUploader() {
// Image uploading states
  const dndRef = useRef(); // Access DnD element reference and its current state
  const [isDragging, setIsDragging] = useState(false);
  const [isUploading, setIsUploading] = useState(false);
  const [uploadedImageUrl, setUploadedImageUrl] = useState('');
  const [src, { blur }] = useProgressiveImg(
    '',
    uploadedImageUrl
  );
  const [uploadedImageName, setUploadedImageName] = useState('image');
  // CSS Filters
  const { activeTool } = useContext(ToolsContext);
  const [options, setOptions] = useState(DEFAULT_OPTIONS);
  const selectedFilter = options[activeTool];

  // Get the file's data and send to clodinary
  const onFileChange = async e => {
    let formData = new FormData();
    formData.append('file', e.target.files[0]);
    formData.append('upload_preset', 'Edite_App');
    setIsUploading(true);

    let data = await api.post('/image/upload', formData);

    const file = data.data;

    setIsDragging(false);
    setIsUploading(false);
    setUploadedImageUrl(file.secure_url);
    setUploadedImageName(file.original_filename);
  }

   // Get slider value according to the tools
  const handleSliderChange = ({ target }) => {
    setOptions(prevOptions => {
      return prevOptions.map((option, index) => {
        if (index !== activeTool) return option
        return { ...option, value: target.value }
      })
    })
  }

  // Get CSS filters and return as a object
  const handleImageStyling = async () => {
    const filters = options.map(option => {
      return `${option.property}(${option.value}${option.unit})`
    })

    return filters.join(' ');
 I }
}

注意:为了更好地解释而不只是给出太多代码,你看上面那个,基本上,我得到一个CSS过滤器列表(JSON 文件)并使用 Cloudinary API 来 post 数据并创建动态 URL。虽然 Cloudinary 支持图像转换,但我总是卡在这个话题上。

Cloudinary 将无法使用 JSON 格式的过滤器,因此,您需要将这些过滤器从 JSON 文件映射到 Cloudinary image transformations. To do that, you will want to create some code/class that handles different input options from your JSON file and converts them to syntax using Cloudinary transformations. E.g. Brightness to e_brightness, Sepia effect to e_sepia 等。

完成后有两种选择:

  1. 如果您希望 Cloudinary 上的原始图像成为应用了滤镜的图像,您将需要使用 incoming transformation。这是在图像 之前 将请求的 Cloudinary 转换应用到图像存储在您的帐户中的地方。应用了转换的输出图像将存储在您的帐户中。
  2. 另一种方法是上传原始图像(未修改)并请求使用 eager transformations 生成转换后的版本。这会造成原始图像没有任何转换的情况,您将创建具有不同转换的 'derived' 版本,在您的情况下将是基于 JSON 文件的转换。