???? Issue
I'm making an app to edit images and I'm stuck when it is about downloading the images after applying the filters. As expected, the user can drag & drop (or just upload) an image (creating a dynamic URL on Cloudinary) and apply the CSS filters to the uploaded image.
So, basically, I want to save the image into the Cloudinary API, but also applying the filters.
????️ Architecture
Edite web app architecture or more about here
⚙️ Reproduce the issue
You can reproduce this issue by cloning the Edite GitHub repository and following the guide to set up the services.
???? Code
Note: see that src is the root
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 }
}
Note: To explain better and not just give too much code, you see above that, basically, I get a CSS filters list (JSON file) and also use Cloudinary API to post the data and create a dynamic URL. Although Cloudinary has support for image transformations, I always get stuck on this topic.